commit
a3f7089f19
@ -0,0 +1,10 @@
|
||||
#include "claw44.h"
|
||||
#include "ssd1306.h"
|
||||
|
||||
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||
#ifdef SSD1306OLED
|
||||
return process_record_gfx(keycode,record) && process_record_user(keycode, record);
|
||||
#else
|
||||
return process_record_user(keycode, record);
|
||||
#endif
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef KEYBOARD_claw44_rev1
|
||||
#include "rev1.h"
|
||||
#endif
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
#include <serial_config.h>
|
||||
|
||||
#define USE_I2C
|
||||
#define USE_SERIAL
|
||||
|
||||
#define NO_ACTION_MACRO
|
||||
#define NO_ACTION_FUNCTION
|
@ -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 or 400kHz (see ./i2c.h SCL_CLOCK)
|
||||
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,46 @@
|
||||
#pragma once
|
||||
|
||||
#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 400kHz
|
||||
#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();
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//#define USE_MATRIX_I2C
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
#define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
||||
|
||||
#define SSD1306OLED
|
||||
|
||||
#define USE_SERIAL_PD2
|
||||
|
||||
#define TAPPING_TERM 200
|
@ -0,0 +1,169 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#ifdef PROTOCOL_LUFA
|
||||
#include "lufa.h"
|
||||
#include "split_util.h"
|
||||
#endif
|
||||
#ifdef SSD1306OLED
|
||||
#include "ssd1306.h"
|
||||
#endif
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
extern uint8_t is_master;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
LOWER,
|
||||
RAISE
|
||||
};
|
||||
|
||||
enum macro_keycodes {
|
||||
KC_SAMPLEMACRO,
|
||||
};
|
||||
|
||||
#define KC_ KC_TRNS
|
||||
#define KC_RST RESET
|
||||
#define KC_L_SPC LT(_LOWER, KC_SPC) // lower
|
||||
#define KC_R_ENT LT(_RAISE, KC_ENT) // raise
|
||||
#define KC_G_JA LGUI_T(KC_LANG1) // cmd or win
|
||||
#define KC_G_EN LGUI_T(KC_LANG2) // cmd or win
|
||||
#define KC_C_BS LCTL_T(KC_BSPC) // ctrl
|
||||
#define KC_A_DEL ALT_T(KC_DEL) // alt
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_QWERTY] = LAYOUT( \
|
||||
//,--------+--------+---------+--------+---------+--------. ,--------+---------+--------+---------+--------+--------.
|
||||
KC_ESC , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_MINS,
|
||||
//|--------+--------+---------+--------+---------+--------| |--------+---------+--------+---------+--------+--------|
|
||||
KC_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, KC_RSFT,
|
||||
//`--------+--------+---------+--------+---------+--------/ \--------+---------+--------+---------+--------+--------'
|
||||
KC_A_DEL, KC_G_EN, KC_L_SPC, KC_C_BS, KC_C_BS, KC_R_ENT, KC_G_JA, KC_A_DEL
|
||||
// `----------+--------+---------+--------' `--------+---------+--------+---------'
|
||||
),
|
||||
|
||||
// \ ^ ! & | @ = + * % -
|
||||
// ( # $ " ' ~ ← ↓ ↑ → ` )
|
||||
// { [ ] }
|
||||
|
||||
[_RAISE] = LAYOUT( \
|
||||
//,--------+--------+--------+--------+--------+--------. ,--------+--------+--------+--------+--------+--------.
|
||||
_______, KC_BSLS, KC_CIRC, KC_EXLM, KC_AMPR, KC_PIPE, KC_AT , KC_EQL , KC_PLUS, KC_ASTR, KC_PERC, KC_MINS,
|
||||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
|
||||
KC_LPRN, KC_HASH, KC_DLR , KC_DQT , KC_QUOT, KC_TILD, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, KC_GRV , KC_RPRN,
|
||||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
|
||||
_______, _______, _______, _______, KC_LCBR, KC_LBRC, KC_RBRC, KC_RCBR, _______, _______, _______, _______,
|
||||
//`--------+--------+--------+--------+--------+--------/ \--------+--------+--------+--------+--------+--------'
|
||||
_______, _______, _______, _______, _______, _______, _______, RESET
|
||||
// `--------+--------+--------+--------' `--------+--------+--------+--------'
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT( \
|
||||
//,--------+--------+--------+--------+--------+--------. ,--------+--------+--------+--------+--------+--------.
|
||||
KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , _______, KC_EQL , KC_PLUS, KC_ASTR, KC_PERC, KC_MINS,
|
||||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
|
||||
_______, KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , _______,
|
||||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
|
||||
KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 , _______, _______, KC_COMM, KC_DOT , KC_SLSH, _______,
|
||||
//`--------+--------+--------+--------+--------+--------/ \--------+--------+--------+--------+--------+--------'
|
||||
RESET , _______, _______, _______, _______, _______, _______, _______
|
||||
// `--------+--------+--------+--------' `--------+--------+--------+--------'
|
||||
),
|
||||
};
|
||||
|
||||
void matrix_init_user(void) {
|
||||
//SSD1306 OLED init, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
iota_gfx_init(!has_usb()); // turns on the display
|
||||
#endif
|
||||
}
|
||||
|
||||
//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
// When add source files to SRC in rules.mk, you can use functions.
|
||||
const char *read_layer_state(void);
|
||||
const char *read_logo(void);
|
||||
void set_keylog(uint16_t keycode, keyrecord_t *record);
|
||||
const char *read_keylog(void);
|
||||
const char *read_keylogs(void);
|
||||
|
||||
// const char *read_mode_icon(bool swap);
|
||||
// const char *read_host_led_state(void);
|
||||
// void set_timelog(void);
|
||||
// const char *read_timelog(void);
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
iota_gfx_task();
|
||||
}
|
||||
|
||||
void matrix_render_user(struct CharacterMatrix *matrix) {
|
||||
if (is_master) {
|
||||
// If you want to change the display of OLED, you need to change here
|
||||
matrix_write_ln(matrix, read_layer_state());
|
||||
matrix_write_ln(matrix, read_keylog());
|
||||
matrix_write_ln(matrix, read_keylogs());
|
||||
//matrix_write_ln(matrix, read_mode_icon(keymap_config.swap_lalt_lgui));
|
||||
//matrix_write_ln(matrix, read_host_led_state());
|
||||
//matrix_write_ln(matrix, read_timelog());
|
||||
} else {
|
||||
matrix_write(matrix, read_logo());
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_update(struct CharacterMatrix *dest, const struct CharacterMatrix *source) {
|
||||
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
|
||||
memcpy(dest->display, source->display, sizeof(dest->display));
|
||||
dest->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void iota_gfx_task_user(void) {
|
||||
struct CharacterMatrix matrix;
|
||||
matrix_clear(&matrix);
|
||||
matrix_render_user(&matrix);
|
||||
matrix_update(&display, &matrix);
|
||||
}
|
||||
#endif//SSD1306OLED
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
if (record->event.pressed) {
|
||||
#ifdef SSD1306OLED
|
||||
set_keylog(keycode, record);
|
||||
#endif
|
||||
// set_timelog();
|
||||
}
|
||||
|
||||
switch (keycode) {
|
||||
case QWERTY:
|
||||
if (record->event.pressed) {
|
||||
set_single_persistent_default_layer(_QWERTY);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case LOWER:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_LOWER);
|
||||
} else {
|
||||
layer_off(_LOWER);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case RAISE:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_RAISE);
|
||||
} else {
|
||||
layer_off(_RAISE);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//#define USE_MATRIX_I2C
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
#define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
||||
|
||||
#define SSD1306OLED
|
||||
|
||||
#define USE_SERIAL_PD2
|
||||
|
||||
#define TAPPING_TERM 180
|
||||
#define IGNORE_MOD_TAP_INTERRUPT
|
@ -0,0 +1,221 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#ifdef PROTOCOL_LUFA
|
||||
#include "lufa.h"
|
||||
#include "split_util.h"
|
||||
#endif
|
||||
#ifdef SSD1306OLED
|
||||
#include "ssd1306.h"
|
||||
#endif
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
extern uint8_t is_master;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
LOWER,
|
||||
RAISE
|
||||
};
|
||||
|
||||
enum macro_keycodes {
|
||||
KC_SAMPLEMACRO,
|
||||
};
|
||||
|
||||
// common
|
||||
#define KC_ KC_TRNS
|
||||
#define KC_XXXX KC_NO
|
||||
#define KC_RST RESET
|
||||
#define KC_VD KC__VOLDOWN
|
||||
#define KC_VU KC__VOLUP
|
||||
|
||||
// layer
|
||||
#define KC_L_SPC LT(_LOWER, KC_SPC)
|
||||
#define KC_R_ENT LT(_RAISE, KC_ENT)
|
||||
|
||||
// shift_t
|
||||
#define KC_S_TAB LSFT_T(KC_TAB)
|
||||
#define KC_S_ESC LSFT_T(KC_ESC)
|
||||
#define KC_S_JA LSFT_T(KC_LANG1)
|
||||
#define KC_S_EN LSFT_T(KC_LANG2)
|
||||
|
||||
// cmd_t
|
||||
#define KC_M_F LCMD_T(KC_F)
|
||||
#define KC_M_D LCMD_T(KC_D)
|
||||
#define KC_M_J LCMD_T(KC_J)
|
||||
#define KC_M_K LCMD_T(KC_K)
|
||||
|
||||
// ctl_t
|
||||
#define KC_C_S LCTL_T(KC_S)
|
||||
#define KC_C_L LCTL_T(KC_L)
|
||||
#define KC_C_BS LCTL_T(KC_BSPC)
|
||||
|
||||
// alt_t
|
||||
#define KC_A_D ALT_T(KC_D)
|
||||
#define KC_A_K ALT_T(KC_K)
|
||||
#define KC_A_Z ALT_T(KC_Z)
|
||||
#define KC_A_SL ALT_T(KC_SLSH)
|
||||
#define KC_A_DEL ALT_T(KC_DEL)
|
||||
|
||||
// cmd+shift_t
|
||||
#define KC_MS_Q SCMD_T(KC_Q)
|
||||
#define KC_MS_A SCMD_T(KC_A)
|
||||
#define KC_MS_S SCMD_T(KC_S)
|
||||
#define KC_MS_SC SCMD_T(KC_SCLN)
|
||||
#define KC_MS_ESC SCMD_T(KC_ESC)
|
||||
|
||||
//
|
||||
#define KC_MR RCMD(KC_R)
|
||||
#define KC_MF RCMD(KC_F)
|
||||
#define KC_MW RCMD(KC_W)
|
||||
#define KC_MX RCMD(KC_X)
|
||||
#define KC_MC RCMD(KC_C)
|
||||
#define KC_MV RCMD(KC_V)
|
||||
#define KC_MTAB RCMD(KC_TAB)
|
||||
#define KC_MSF RCMD(RSFT(KC_F))
|
||||
#define KC_MSR RCMD(RSFT(KC_R))
|
||||
#define KC_MST RCMD(RSFT(KC_T))
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
// M_ = LCMD_T(
|
||||
// A_ = ALT_T(
|
||||
// C_ = LCTL_T(
|
||||
// MS_ = SMD_T(
|
||||
// R_ = LT(_RAISE
|
||||
// L_ = LT(_LOWER
|
||||
|
||||
[_QWERTY] = LAYOUT_kc( \
|
||||
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
|
||||
ESC , Q , W , E , R , T , Y , U , I , O , P ,MINS,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
S_TAB, A ,C_S , D ,M_F , G , H ,M_J , K ,C_L ,SCLN,S_ESC,
|
||||
//|----+----+----+----+----+----+ |----+----+----+----+----+----|
|
||||
, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH, ,
|
||||
//`----+----+----+----+----+----/ \----+----+----+----+----+----'
|
||||
A_DEL,S_EN,L_SPC,C_BS, C_BS,R_ENT,S_JA,A_DEL
|
||||
// `----+----+----+----' `----+----+----+----'
|
||||
),
|
||||
|
||||
// \ ^ ! & | @ = + * % -
|
||||
// ( # $ " ' ~ ← ↓ ↑ → ` )
|
||||
// { [ ] }
|
||||
|
||||
[_RAISE] = LAYOUT_kc( \
|
||||
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
|
||||
,BSLS,CIRC,EXLM,AMPR,PIPE, AT ,EQL ,PLUS,ASTR,PERC,MINS,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
LPRN,HASH,DLR ,DQT ,QUOT,TILD, LEFT,DOWN, UP ,RGHT,GRV ,RPRN,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
, , , ,LCBR,LBRC, RBRC,RCBR, , , , ,
|
||||
//`----+----+----+----+----+----/ \----+----+----+----+----+----'
|
||||
, ,BSPC, , , , ,RST
|
||||
// `----+----+----+----' `----+----+----+----'
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT_kc( \
|
||||
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
|
||||
, , ,MSF ,MSR ,MST , ,EQL ,PLUS,ASTR,PERC,MINS,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , ,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
, , , , , , , ,COMM,DOT ,SLSH, ,
|
||||
//`----+----+----+--+-+----+----/ \----+----+----+----+----+----'
|
||||
RST , , , , ,DEL , ,
|
||||
// `----+----+----+----' `----+----+----+----'
|
||||
),
|
||||
};
|
||||
|
||||
void matrix_init_user(void) {
|
||||
//SSD1306 OLED init, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
iota_gfx_init(!has_usb()); // turns on the display
|
||||
#endif
|
||||
}
|
||||
|
||||
//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
// When add source files to SRC in rules.mk, you can use functions.
|
||||
const char *read_layer_state(void);
|
||||
const char *read_logo(void);
|
||||
void set_keylog(uint16_t keycode, keyrecord_t *record);
|
||||
const char *read_keylog(void);
|
||||
const char *read_keylogs(void);
|
||||
|
||||
// const char *read_mode_icon(bool swap);
|
||||
// const char *read_host_led_state(void);
|
||||
// void set_timelog(void);
|
||||
// const char *read_timelog(void);
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
iota_gfx_task();
|
||||
}
|
||||
|
||||
void matrix_render_user(struct CharacterMatrix *matrix) {
|
||||
if (is_master) {
|
||||
// If you want to change the display of OLED, you need to change here
|
||||
matrix_write_ln(matrix, read_layer_state());
|
||||
matrix_write_ln(matrix, read_keylog());
|
||||
matrix_write_ln(matrix, read_keylogs());
|
||||
//matrix_write_ln(matrix, read_mode_icon(keymap_config.swap_lalt_lgui));
|
||||
//matrix_write_ln(matrix, read_host_led_state());
|
||||
//matrix_write_ln(matrix, read_timelog());
|
||||
} else {
|
||||
matrix_write(matrix, read_logo());
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_update(struct CharacterMatrix *dest, const struct CharacterMatrix *source) {
|
||||
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
|
||||
memcpy(dest->display, source->display, sizeof(dest->display));
|
||||
dest->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void iota_gfx_task_user(void) {
|
||||
struct CharacterMatrix matrix;
|
||||
matrix_clear(&matrix);
|
||||
matrix_render_user(&matrix);
|
||||
matrix_update(&display, &matrix);
|
||||
}
|
||||
#endif//SSD1306OLED
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
if (record->event.pressed) {
|
||||
#ifdef SSD1306OLED
|
||||
set_keylog(keycode, record);
|
||||
#endif
|
||||
// set_timelog();
|
||||
}
|
||||
|
||||
switch (keycode) {
|
||||
case QWERTY:
|
||||
if (record->event.pressed) {
|
||||
set_single_persistent_default_layer(_QWERTY);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case LOWER:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_LOWER);
|
||||
} else {
|
||||
layer_off(_LOWER);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case RAISE:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_RAISE);
|
||||
} else {
|
||||
layer_off(_RAISE);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,243 @@
|
||||
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
|
||||
// See gfxfont.h for newer custom bitmap font info.
|
||||
|
||||
#ifndef FONT5X7_H
|
||||
#define FONT5X7_H
|
||||
|
||||
#ifdef __AVR__
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#else
|
||||
#define PROGMEM
|
||||
#endif
|
||||
|
||||
// Standard ASCII 5x7 font
|
||||
const unsigned char font[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
|
||||
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
|
||||
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
|
||||
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
|
||||
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
|
||||
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
|
||||
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
|
||||
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
|
||||
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
|
||||
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
|
||||
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
|
||||
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
|
||||
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
|
||||
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
|
||||
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
|
||||
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
|
||||
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
|
||||
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
|
||||
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
|
||||
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
|
||||
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
|
||||
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
|
||||
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
|
||||
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
|
||||
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
|
||||
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
|
||||
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
|
||||
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
|
||||
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
|
||||
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
|
||||
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
|
||||
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
|
||||
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
|
||||
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
|
||||
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
|
||||
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
|
||||
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
|
||||
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
|
||||
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
|
||||
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
|
||||
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
|
||||
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
|
||||
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
|
||||
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
|
||||
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
|
||||
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
|
||||
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
|
||||
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
|
||||
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
|
||||
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
|
||||
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
|
||||
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
|
||||
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
|
||||
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
|
||||
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
|
||||
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
|
||||
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
|
||||
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
|
||||
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
|
||||
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
|
||||
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
|
||||
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
|
||||
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
|
||||
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
|
||||
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
|
||||
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
|
||||
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
|
||||
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
|
||||
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
|
||||
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
|
||||
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
|
||||
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
|
||||
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
|
||||
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
|
||||
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
|
||||
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
|
||||
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
|
||||
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
|
||||
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
|
||||
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
|
||||
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
|
||||
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
|
||||
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
|
||||
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
|
||||
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
|
||||
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
|
||||
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
|
||||
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
|
||||
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
|
||||
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
|
||||
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
|
||||
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
|
||||
0x7C, 0x18, 0x24, 0x24, 0x18, 0x00,
|
||||
0x18, 0x24, 0x24, 0x18, 0x7C, 0x00,
|
||||
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
|
||||
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
|
||||
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
|
||||
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
|
||||
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
|
||||
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
|
||||
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
|
||||
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
|
||||
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
|
||||
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
|
||||
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
|
||||
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
|
||||
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFC, 0xFC, 0xFC, 0xFC, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x80, 0x80, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
|
||||
0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0xC0, 0xF0, 0xF8, 0xF8,
|
||||
0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0xE0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC,
|
||||
0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00,
|
||||
0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E,
|
||||
0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00,
|
||||
0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B,
|
||||
0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00,
|
||||
0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE,
|
||||
0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xF8, 0xFC, 0xFE,
|
||||
0xFF, 0x1F, 0x07, 0x07, 0x07, 0x07,
|
||||
0x1F, 0x1F, 0x1F, 0x1E, 0x18, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
0x00, 0x00, 0x00, 0x9E, 0xDF, 0xDF,
|
||||
0xCF, 0xC7, 0xE7, 0xE7, 0xE7, 0xFF,
|
||||
0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03,
|
||||
0x3F, 0xFF, 0xFF, 0xFE, 0xC0, 0x00,
|
||||
0xF0, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xC0, 0xFC, 0xFF, 0xFF,
|
||||
0x3F, 0x03, 0x00, 0xC0, 0xF0, 0xF8,
|
||||
0xFE, 0x9F, 0x87, 0x83, 0x80, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x00,
|
||||
0x00, 0xE0, 0xF8, 0xFC, 0xBF, 0x8F,
|
||||
0x83, 0x81, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
|
||||
0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00,
|
||||
0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F,
|
||||
0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00,
|
||||
0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20,
|
||||
0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00,
|
||||
0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F,
|
||||
0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0x1F, 0x3F,
|
||||
0x7F, 0x7C, 0x78, 0x70, 0x70, 0x78,
|
||||
0x7E, 0x3E, 0x3E, 0x0E, 0x06, 0x00,
|
||||
0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x00,
|
||||
0x00, 0x00, 0x1F, 0x3F, 0x7F, 0x7F,
|
||||
0x79, 0x71, 0x70, 0x30, 0x38, 0x3F,
|
||||
0x7F, 0x7F, 0x7F, 0x60, 0x00, 0x00,
|
||||
0x00, 0x01, 0x1F, 0x7F, 0x7F, 0x7E,
|
||||
0x7F, 0x1F, 0x01, 0x00, 0x01, 0x3F,
|
||||
0x7F, 0x7E, 0x7F, 0x7F, 0x0F, 0x01,
|
||||
0x00, 0x00, 0x00, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x7F,
|
||||
0x7F, 0x7F, 0x7F, 0x03, 0x03, 0x00,
|
||||
0x00, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x7F, 0x7F, 0x7F, 0x7F,
|
||||
0x07, 0x03, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
#endif // FONT5X7_H
|
@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include "claw44.h"
|
||||
|
||||
char host_led_state_str[24];
|
||||
|
||||
const char *read_host_led_state(void)
|
||||
{
|
||||
uint8_t leds = host_keyboard_leds();
|
||||
snprintf(host_led_state_str, sizeof(host_led_state_str), "NL:%s CL:%s SL:%s",
|
||||
(leds & (1 << USB_LED_NUM_LOCK)) ? "on" : "- ",
|
||||
(leds & (1 << USB_LED_CAPS_LOCK)) ? "on" : "- ",
|
||||
(leds & (1 << USB_LED_SCROLL_LOCK)) ? "on" : "- ");
|
||||
|
||||
return host_led_state_str;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
#include <stdio.h>
|
||||
#include "claw44.h"
|
||||
|
||||
char keylog_str[24] = {};
|
||||
char keylogs_str[21] = {};
|
||||
int keylogs_str_idx = 0;
|
||||
|
||||
const char code_to_name[60] = {
|
||||
' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
|
||||
'R', 'E', 'B', 'T', ' ', ' ', ' ', ' ', ' ', ' ',
|
||||
' ', ';', '\'', ' ', ',', '.', '/', ' ', ' ', ' '};
|
||||
|
||||
void set_keylog(uint16_t keycode, keyrecord_t *record) {
|
||||
char name = ' ';
|
||||
if (keycode < 60) {
|
||||
name = code_to_name[keycode];
|
||||
}
|
||||
|
||||
// update keylog
|
||||
snprintf(keylog_str, sizeof(keylog_str), "%dx%d, k%2d : %c",
|
||||
record->event.key.row, record->event.key.col,
|
||||
keycode, name);
|
||||
|
||||
// update keylogs
|
||||
if (keylogs_str_idx == sizeof(keylogs_str) - 1) {
|
||||
keylogs_str_idx = 0;
|
||||
for (int i = 0; i < sizeof(keylogs_str) - 1; i++) {
|
||||
keylogs_str[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
keylogs_str[keylogs_str_idx] = name;
|
||||
keylogs_str_idx++;
|
||||
}
|
||||
|
||||
const char *read_keylog(void) {
|
||||
return keylog_str;
|
||||
}
|
||||
|
||||
const char *read_keylogs(void) {
|
||||
return keylogs_str;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
#include <stdio.h>
|
||||
#include "claw44.h"
|
||||
|
||||
#define L_BASE 0
|
||||
#define L_LOWER (1<<_LOWER)
|
||||
#define L_RAISE (1<<_RAISE)
|
||||
#define L_ADJUST (1<<_ADJUST)
|
||||
#define L_ADJUST_TRI (L_ADJUST|L_RAISE|L_LOWER)
|
||||
|
||||
char layer_state_str[24];
|
||||
|
||||
const char *read_layer_state(void) {
|
||||
switch (layer_state)
|
||||
{
|
||||
case L_BASE:
|
||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Default");
|
||||
break;
|
||||
case L_RAISE:
|
||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Raise");
|
||||
break;
|
||||
case L_LOWER:
|
||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Lower");
|
||||
break;
|
||||
case L_ADJUST:
|
||||
case L_ADJUST_TRI:
|
||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Adjust");
|
||||
break;
|
||||
default:
|
||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Undef-%ld", layer_state);
|
||||
}
|
||||
|
||||
return layer_state_str;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#include "claw44.h"
|
||||
|
||||
const char *read_logo(void) {
|
||||
static char logo[] = {
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
|
||||
0};
|
||||
|
||||
return logo;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include "claw44.h"
|
||||
|
||||
char mode_icon[24];
|
||||
|
||||
const char *read_mode_icon(bool swap) {
|
||||
static char logo[][2][3] = {{{0x95, 0x96, 0}, {0xb5, 0xb6, 0}}, {{0x97, 0x98, 0}, {0xb7, 0xb8, 0}}};
|
||||
if (swap == false) {
|
||||
snprintf(mode_icon, sizeof(mode_icon), "%s\n%s", logo[0][0], logo[0][1]);
|
||||
} else {
|
||||
snprintf(mode_icon, sizeof(mode_icon), "%s\n%s", logo[1][0], logo[1][1]);
|
||||
}
|
||||
|
||||
return mode_icon;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
#include <stdio.h>
|
||||
|
||||
extern rgblight_config_t rgblight_config;
|
||||
char rbf_info_str[24];
|
||||
const char *read_rgb_info(void) {
|
||||
|
||||
snprintf(rbf_info_str, sizeof(rbf_info_str), "%s %2d h%3d s%3d v%3d",
|
||||
rgblight_config.enable ? "on" : "- ", rgblight_config.mode,
|
||||
rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
return rbf_info_str;
|
||||
}
|
||||
#endif
|
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include "claw44.h"
|
||||
|
||||
char timelog_str[24] = {};
|
||||
int last_time = 0;
|
||||
int elapsed_time = 0;
|
||||
|
||||
void set_timelog(void) {
|
||||
elapsed_time = timer_elapsed(last_time);
|
||||
last_time = timer_read();
|
||||
snprintf(timelog_str, sizeof(timelog_str), "lt:%5d, et:%5d", last_time, elapsed_time);
|
||||
}
|
||||
|
||||
const char *read_timelog(void) {
|
||||
return timelog_str;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
# Claw44
|
||||
|
||||
![Claw44](https://i.imgur.com/5a8iogl.jpg)
|
||||
|
||||
A split keyboard with 3x6 vertically staggered keys and 4 thumb keys.
|
||||
|
||||
Keyboard Maintainer: [@yfuku_](https://twitter.com/yfuku_)
|
||||
Hardware Supported: Claw44 PCB, ProMicro
|
||||
Hardware Availability: https://yfuku.booth.pm/
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make claw44:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x3060
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER yfuku
|
||||
#define PRODUCT claw44
|
||||
#define DESCRIPTION A split keyboard with 3x6 vertically staggered keys and 4 thumb keys
|
||||
|
||||
/* key matrix size */
|
||||
// Rows are doubled-up
|
||||
#define MATRIX_ROWS 8
|
||||
#define MATRIX_COLS 7
|
||||
#define MATRIX_ROW_PINS { D4, C6, D7, E6 }
|
||||
|
||||
// wiring of each half
|
||||
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2 }
|
||||
// #define MATRIX_COL_PINS { B2, B3, B1, F7, F6, F5, F4 } //uncomment this line and comment line above if you need to reverse left-to-right key order
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
// #define BACKLIGHT_LEVELS 3
|
||||
|
||||
/* 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
|
||||
|
||||
/* ws2812 RGB LED */
|
||||
/*
|
||||
#define RGB_DI_PIN D3
|
||||
|
||||
#define RGBLED_NUM 12 // 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
|
@ -0,0 +1,357 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* scan matrix
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#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"
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
# include "i2c.h"
|
||||
#else // USE_SERIAL
|
||||
# include "split_scomm.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;
|
||||
uint8_t is_master = 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);
|
||||
static uint8_t matrix_master_scan(void);
|
||||
|
||||
|
||||
__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;
|
||||
TXLED0;
|
||||
RXLED0;
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
matrix_debouncing[i] = 0;
|
||||
}
|
||||
|
||||
is_master = has_usb();
|
||||
|
||||
matrix_init_quantum();
|
||||
}
|
||||
|
||||
uint8_t _matrix_scan(void)
|
||||
{
|
||||
// Right hand is stored after the left in the matirx 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_MATRIX_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) {
|
||||
int i;
|
||||
for (i = 0; i < ROWS_PER_HAND-1; ++i) {
|
||||
matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
|
||||
}
|
||||
matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
|
||||
i2c_master_stop();
|
||||
} else {
|
||||
i2c_error: // the cable is disconnceted, or something else went wrong
|
||||
i2c_reset_state();
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // USE_SERIAL
|
||||
|
||||
int serial_transaction(int master_changed) {
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int ret=serial_update_buffers(master_changed);
|
||||
#else
|
||||
int ret=serial_update_buffers();
|
||||
#endif
|
||||
if (ret ) {
|
||||
if(ret==2) RXLED1;
|
||||
return 1;
|
||||
}
|
||||
RXLED0;
|
||||
memcpy(&matrix[slaveOffset],
|
||||
(void *)serial_slave_buffer, SERIAL_SLAVE_BUFFER_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
if (is_master) {
|
||||
matrix_master_scan();
|
||||
}else{
|
||||
matrix_slave_scan();
|
||||
int offset = (isLeftHand) ? ROWS_PER_HAND : 0;
|
||||
memcpy(&matrix[offset],
|
||||
(void *)serial_master_buffer, SERIAL_MASTER_BUFFER_LENGTH);
|
||||
matrix_scan_quantum();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t matrix_master_scan(void) {
|
||||
|
||||
int ret = _matrix_scan();
|
||||
int mchanged = 1;
|
||||
|
||||
int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
// for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */
|
||||
// i2c_slave_buffer[i] = matrix[offset+i];
|
||||
// }
|
||||
#else // USE_SERIAL
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
mchanged = memcmp((void *)serial_master_buffer,
|
||||
&matrix[offset], SERIAL_MASTER_BUFFER_LENGTH);
|
||||
#endif
|
||||
memcpy((void *)serial_master_buffer,
|
||||
&matrix[offset], SERIAL_MASTER_BUFFER_LENGTH);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
if( i2c_transaction() ) {
|
||||
#else // USE_SERIAL
|
||||
if( serial_transaction(mchanged) ) {
|
||||
#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_MATRIX_I2C
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */
|
||||
i2c_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
#else // USE_SERIAL
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int change = 0;
|
||||
#endif
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
if( serial_slave_buffer[i] != matrix[offset+i] )
|
||||
change = 1;
|
||||
#endif
|
||||
serial_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
slave_buffer_change_count += change;
|
||||
#endif
|
||||
#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,8 @@
|
||||
#include "claw44.h"
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
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);
|
||||
}
|
||||
#endif
|
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "../claw44.h"
|
||||
|
||||
//void promicro_bootloader_jmp(bool program);
|
||||
#include "quantum.h"
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
//rgb led driver
|
||||
#include "ws2812.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_I2C
|
||||
#include <stddef.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//void promicro_bootloader_jmp(bool program);
|
||||
#define LAYOUT( \
|
||||
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
|
||||
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
|
||||
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
|
||||
L30, L31, L32, L33, R30, R31, R32, R33 \
|
||||
) \
|
||||
{ \
|
||||
{ L00, L01, L02, L03, L04, L05 }, \
|
||||
{ L10, L11, L12, L13, L14, L15 }, \
|
||||
{ L20, L21, L22, L23, L24, L25 }, \
|
||||
{ KC_NO, KC_NO, L30, L31, L32, L33 }, \
|
||||
{ R05, R04, R03, R02, R01, R00 }, \
|
||||
{ R15, R14, R13, R12, R11, R10 }, \
|
||||
{ R25, R24, R23, R22, R21, R20 }, \
|
||||
{ KC_NO, KC_NO, R33, R32, R31, R30 } \
|
||||
}
|
||||
|
||||
#define LAYOUT_kc( \
|
||||
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
|
||||
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
|
||||
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
|
||||
L30, L31, L32, L33, R30, R31, R32, R33 \
|
||||
) \
|
||||
LAYOUT( \
|
||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05, \
|
||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15, \
|
||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25, \
|
||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##R30, KC_##R31, KC_##R32, KC_##R33 \
|
||||
)
|
||||
|
||||
enum layer_number {
|
||||
_QWERTY = 0,
|
||||
_LOWER,
|
||||
_RAISE,
|
||||
_ADJUST,
|
||||
};
|
@ -0,0 +1,31 @@
|
||||
SRC += rev1/matrix.c
|
||||
SRC += rev1/split_util.c
|
||||
SRC += rev1/split_scomm.c
|
||||
|
||||
# Build Options
|
||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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.
|
||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing
|
||||
|
||||
# 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 you want to change the display of OLED, you need to change here
|
||||
SRC += ./lib/glcdfont.c \
|
||||
./lib/layer_state_reader.c \
|
||||
./lib/logo_reader.c \
|
||||
./lib/keylogger.c \
|
||||
# ./lib/rgb_state_reader.c \
|
||||
# ./lib/mode_icon_reader.c \
|
||||
# ./lib/host_led_state_reader.c \
|
||||
# ./lib/timelogger.c \
|
@ -0,0 +1,4 @@
|
||||
#ifndef SOFT_SERIAL_PIN
|
||||
#define SOFT_SERIAL_PIN D2
|
||||
#define SERIAL_USE_MULTI_TRANSACTION
|
||||
#endif
|
@ -0,0 +1,91 @@
|
||||
#ifdef USE_SERIAL
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
/* --- USE flexible API (using multi-type transaction function) --- */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <split_scomm.h>
|
||||
#include "serial.h"
|
||||
#ifdef CONSOLE_ENABLE
|
||||
#include <print.h>
|
||||
#endif
|
||||
|
||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||
uint8_t volatile status_com = 0;
|
||||
uint8_t volatile status1 = 0;
|
||||
uint8_t slave_buffer_change_count = 0;
|
||||
uint8_t s_change_old = 0xff;
|
||||
uint8_t s_change_new = 0xff;
|
||||
|
||||
SSTD_t transactions[] = {
|
||||
#define GET_SLAVE_STATUS 0
|
||||
/* master buffer not changed, only recive slave_buffer_change_count */
|
||||
{ (uint8_t *)&status_com,
|
||||
0, NULL,
|
||||
sizeof(slave_buffer_change_count), &slave_buffer_change_count,
|
||||
},
|
||||
#define PUT_MASTER_GET_SLAVE_STATUS 1
|
||||
/* master buffer changed need send, and recive slave_buffer_change_count */
|
||||
{ (uint8_t *)&status_com,
|
||||
sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer,
|
||||
sizeof(slave_buffer_change_count), &slave_buffer_change_count,
|
||||
},
|
||||
#define GET_SLAVE_BUFFER 2
|
||||
/* recive serial_slave_buffer */
|
||||
{ (uint8_t *)&status1,
|
||||
0, NULL,
|
||||
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
|
||||
}
|
||||
};
|
||||
|
||||
void serial_master_init(void)
|
||||
{
|
||||
soft_serial_initiator_init(transactions, TID_LIMIT(transactions));
|
||||
}
|
||||
|
||||
void serial_slave_init(void)
|
||||
{
|
||||
soft_serial_target_init(transactions, TID_LIMIT(transactions));
|
||||
}
|
||||
|
||||
// 0 => no error
|
||||
// 1 => slave did not respond
|
||||
// 2 => checksum error
|
||||
int serial_update_buffers(int master_update)
|
||||
{
|
||||
int status, smatstatus;
|
||||
static int need_retry = 0;
|
||||
|
||||
if( s_change_old != s_change_new ) {
|
||||
smatstatus = soft_serial_transaction(GET_SLAVE_BUFFER);
|
||||
if( smatstatus == TRANSACTION_END ) {
|
||||
s_change_old = s_change_new;
|
||||
#ifdef CONSOLE_ENABLE
|
||||
uprintf("slave matrix = %b %b %b %b\n",
|
||||
serial_slave_buffer[0], serial_slave_buffer[1],
|
||||
serial_slave_buffer[2], serial_slave_buffer[3]);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// serial_slave_buffer dosen't change
|
||||
smatstatus = TRANSACTION_END; // dummy status
|
||||
}
|
||||
|
||||
if( !master_update && !need_retry) {
|
||||
status = soft_serial_transaction(GET_SLAVE_STATUS);
|
||||
} else {
|
||||
status = soft_serial_transaction(PUT_MASTER_GET_SLAVE_STATUS);
|
||||
}
|
||||
if( status == TRANSACTION_END ) {
|
||||
s_change_new = slave_buffer_change_count;
|
||||
need_retry = 0;
|
||||
} else {
|
||||
need_retry = 1;
|
||||
}
|
||||
return smatstatus;
|
||||
}
|
||||
|
||||
#endif // SERIAL_USE_MULTI_TRANSACTION
|
||||
#endif /* USE_SERIAL */
|
@ -0,0 +1,24 @@
|
||||
#ifndef SPLIT_COMM_H
|
||||
#define SPLIT_COMM_H
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
/* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */
|
||||
#include "serial.h"
|
||||
|
||||
#else
|
||||
/* --- USE flexible API (using multi-type transaction function) --- */
|
||||
// Buffers for master - slave communication
|
||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
|
||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||
extern uint8_t slave_buffer_change_count;
|
||||
|
||||
void serial_master_init(void);
|
||||
void serial_slave_init(void);
|
||||
int serial_update_buffers(int master_changed);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SPLIT_COMM_H */
|
@ -0,0 +1,70 @@
|
||||
#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"
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
# include "i2c.h"
|
||||
#else
|
||||
# include "split_scomm.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_MATRIX_I2C
|
||||
i2c_master_init();
|
||||
#else
|
||||
serial_master_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_slave_setup(void) {
|
||||
|
||||
#ifdef USE_MATRIX_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();
|
||||
}
|
||||
|
||||
// this code runs before the usb and keyboard is initialized
|
||||
void matrix_setup(void) {
|
||||
split_keyboard_setup();
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#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 matrix_master_OLED_init (void);
|
||||
|
||||
#endif
|
@ -0,0 +1,74 @@
|
||||
SRC += i2c.c
|
||||
SRC += serial.c
|
||||
SRC += ssd1306.c
|
||||
|
||||
# if firmware size over limit, try this option
|
||||
# CFLAGS += -flto
|
||||
|
||||
# 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 = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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 SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
|
||||
CUSTOM_MATRIX = yes
|
||||
|
||||
DEFAULT_FOLDER = claw44/rev1
|
@ -0,0 +1,590 @@
|
||||
/*
|
||||
* WARNING: be careful changing this code, it is very timing dependent
|
||||
*
|
||||
* 2018-10-28 checked
|
||||
* avr-gcc 4.9.2
|
||||
* avr-gcc 5.4.0
|
||||
* avr-gcc 7.3.0
|
||||
*/
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000
|
||||
#endif
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "serial.h"
|
||||
//#include <pro_micro.h>
|
||||
|
||||
#ifdef SOFT_SERIAL_PIN
|
||||
|
||||
#ifdef __AVR_ATmega32U4__
|
||||
// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
|
||||
#ifdef USE_I2C
|
||||
#if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
|
||||
#error Using ATmega32U4 I2C, so can not use PD0, PD1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
|
||||
#define SERIAL_PIN_DDR DDRD
|
||||
#define SERIAL_PIN_PORT PORTD
|
||||
#define SERIAL_PIN_INPUT PIND
|
||||
#if SOFT_SERIAL_PIN == D0
|
||||
#define SERIAL_PIN_MASK _BV(PD0)
|
||||
#define EIMSK_BIT _BV(INT0)
|
||||
#define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
|
||||
#define SERIAL_PIN_INTERRUPT INT0_vect
|
||||
#elif SOFT_SERIAL_PIN == D1
|
||||
#define SERIAL_PIN_MASK _BV(PD1)
|
||||
#define EIMSK_BIT _BV(INT1)
|
||||
#define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
|
||||
#define SERIAL_PIN_INTERRUPT INT1_vect
|
||||
#elif SOFT_SERIAL_PIN == D2
|
||||
#define SERIAL_PIN_MASK _BV(PD2)
|
||||
#define EIMSK_BIT _BV(INT2)
|
||||
#define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
|
||||
#define SERIAL_PIN_INTERRUPT INT2_vect
|
||||
#elif SOFT_SERIAL_PIN == D3
|
||||
#define SERIAL_PIN_MASK _BV(PD3)
|
||||
#define EIMSK_BIT _BV(INT3)
|
||||
#define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
|
||||
#define SERIAL_PIN_INTERRUPT INT3_vect
|
||||
#endif
|
||||
#elif SOFT_SERIAL_PIN == E6
|
||||
#define SERIAL_PIN_DDR DDRE
|
||||
#define SERIAL_PIN_PORT PORTE
|
||||
#define SERIAL_PIN_INPUT PINE
|
||||
#define SERIAL_PIN_MASK _BV(PE6)
|
||||
#define EIMSK_BIT _BV(INT6)
|
||||
#define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
|
||||
#define SERIAL_PIN_INTERRUPT INT6_vect
|
||||
#else
|
||||
#error invalid SOFT_SERIAL_PIN value
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error serial.c now support ATmega32U4 only
|
||||
#endif
|
||||
|
||||
//////////////// for backward compatibility ////////////////////////////////
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
/* --- USE Simple API (OLD API, compatible with let's split serial.c) */
|
||||
#if SERIAL_SLAVE_BUFFER_LENGTH > 0
|
||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||
#endif
|
||||
#if SERIAL_MASTER_BUFFER_LENGTH > 0
|
||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||
#endif
|
||||
uint8_t volatile status0 = 0;
|
||||
|
||||
SSTD_t transactions[] = {
|
||||
{ (uint8_t *)&status0,
|
||||
#if SERIAL_MASTER_BUFFER_LENGTH > 0
|
||||
sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer,
|
||||
#else
|
||||
0, (uint8_t *)NULL,
|
||||
#endif
|
||||
#if SERIAL_SLAVE_BUFFER_LENGTH > 0
|
||||
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
|
||||
#else
|
||||
0, (uint8_t *)NULL,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
void serial_master_init(void)
|
||||
{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
|
||||
|
||||
void serial_slave_init(void)
|
||||
{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
|
||||
|
||||
// 0 => no error
|
||||
// 1 => slave did not respond
|
||||
// 2 => checksum error
|
||||
int serial_update_buffers()
|
||||
{
|
||||
int result;
|
||||
result = soft_serial_transaction();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // end of Simple API (OLD API, compatible with let's split serial.c)
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#define NO_INLINE __attribute__((noinline))
|
||||
#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
|
||||
|
||||
// parity check
|
||||
#define ODD_PARITY 1
|
||||
#define EVEN_PARITY 0
|
||||
#define PARITY EVEN_PARITY
|
||||
|
||||
#ifdef SERIAL_DELAY
|
||||
// custom setup in config.h
|
||||
// #define TID_SEND_ADJUST 2
|
||||
// #define SERIAL_DELAY 6 // micro sec
|
||||
// #define READ_WRITE_START_ADJUST 30 // cycles
|
||||
// #define READ_WRITE_WIDTH_ADJUST 8 // cycles
|
||||
#else
|
||||
// ============ Standard setups ============
|
||||
|
||||
#ifndef SELECT_SOFT_SERIAL_SPEED
|
||||
#define SELECT_SOFT_SERIAL_SPEED 1
|
||||
// 0: about 189kbps
|
||||
// 1: about 137kbps (default)
|
||||
// 2: about 75kbps
|
||||
// 3: about 39kbps
|
||||
// 4: about 26kbps
|
||||
// 5: about 20kbps
|
||||
#endif
|
||||
|
||||
#if __GNUC__ < 6
|
||||
#define TID_SEND_ADJUST 14
|
||||
#else
|
||||
#define TID_SEND_ADJUST 2
|
||||
#endif
|
||||
|
||||
#if SELECT_SOFT_SERIAL_SPEED == 0
|
||||
// Very High speed
|
||||
#define SERIAL_DELAY 4 // micro sec
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_START_ADJUST 33 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_START_ADJUST 34 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 1
|
||||
// High speed
|
||||
#define SERIAL_DELAY 6 // micro sec
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_START_ADJUST 33 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 2
|
||||
// Middle speed
|
||||
#define SERIAL_DELAY 12 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 3
|
||||
// Low speed
|
||||
#define SERIAL_DELAY 24 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 4
|
||||
// Very Low speed
|
||||
#define SERIAL_DELAY 36 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 5
|
||||
// Ultra Low speed
|
||||
#define SERIAL_DELAY 48 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#else
|
||||
#error invalid SELECT_SOFT_SERIAL_SPEED value
|
||||
#endif /* SELECT_SOFT_SERIAL_SPEED */
|
||||
#endif /* SERIAL_DELAY */
|
||||
|
||||
#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2)
|
||||
#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2)
|
||||
|
||||
#define SLAVE_INT_WIDTH_US 1
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
#define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
|
||||
#else
|
||||
#define SLAVE_INT_ACK_WIDTH_UNIT 2
|
||||
#define SLAVE_INT_ACK_WIDTH 4
|
||||
#endif
|
||||
|
||||
static SSTD_t *Transaction_table = NULL;
|
||||
static uint8_t Transaction_table_size = 0;
|
||||
|
||||
inline static void serial_delay(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay(void) {
|
||||
_delay_us(SERIAL_DELAY);
|
||||
}
|
||||
|
||||
inline static void serial_delay_half1(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay_half1(void) {
|
||||
_delay_us(SERIAL_DELAY_HALF1);
|
||||
}
|
||||
|
||||
inline static void serial_delay_half2(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay_half2(void) {
|
||||
_delay_us(SERIAL_DELAY_HALF2);
|
||||
}
|
||||
|
||||
inline static void serial_output(void) ALWAYS_INLINE;
|
||||
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_with_pullup(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_input_with_pullup(void) {
|
||||
SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
uint8_t serial_read_pin(void) {
|
||||
return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
|
||||
}
|
||||
|
||||
inline static void serial_low(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_low(void) {
|
||||
SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static void serial_high(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_high(void) {
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size)
|
||||
{
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size)
|
||||
{
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
serial_input_with_pullup();
|
||||
|
||||
// Enable INT0-INT3,INT6
|
||||
EIMSK |= EIMSK_BIT;
|
||||
#if SERIAL_PIN_MASK == _BV(PE6)
|
||||
// Trigger on falling edge of INT6
|
||||
EICRB &= EICRx_BIT;
|
||||
#else
|
||||
// Trigger on falling edge of INT0-INT3
|
||||
EICRA &= EICRx_BIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Used by the sender to synchronize timing with the reciver.
|
||||
static void sync_recv(void) NO_INLINE;
|
||||
static
|
||||
void sync_recv(void) {
|
||||
for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) {
|
||||
}
|
||||
// This shouldn't hang if the target disconnects because the
|
||||
// serial line will float to high if the target does disconnect.
|
||||
while (!serial_read_pin());
|
||||
}
|
||||
|
||||
// Used by the reciver to send a synchronization signal to the sender.
|
||||
static void sync_send(void) NO_INLINE;
|
||||
static
|
||||
void sync_send(void) {
|
||||
serial_low();
|
||||
serial_delay();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
// Reads a byte from the serial line
|
||||
static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE;
|
||||
static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
|
||||
uint8_t byte, i, p, pb;
|
||||
|
||||
_delay_sub_us(READ_WRITE_START_ADJUST);
|
||||
for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) {
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
if( serial_read_pin() ) {
|
||||
byte = (byte << 1) | 1; p ^= 1;
|
||||
} else {
|
||||
byte = (byte << 1) | 0; p ^= 0;
|
||||
}
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
}
|
||||
/* recive parity bit */
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
pb = serial_read_pin();
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
|
||||
*pterrcount += (p != pb)? 1 : 0;
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Sends a byte with MSB ordering
|
||||
void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
|
||||
void serial_write_chunk(uint8_t data, uint8_t bit) {
|
||||
uint8_t b, p;
|
||||
for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) {
|
||||
if(data & b) {
|
||||
serial_high(); p ^= 1;
|
||||
} else {
|
||||
serial_low(); p ^= 0;
|
||||
}
|
||||
serial_delay();
|
||||
}
|
||||
/* send parity bit */
|
||||
if(p & 1) { serial_high(); }
|
||||
else { serial_low(); }
|
||||
serial_delay();
|
||||
|
||||
serial_low(); // sync_send() / senc_recv() need raise edge
|
||||
}
|
||||
|
||||
static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
|
||||
static
|
||||
void serial_send_packet(uint8_t *buffer, uint8_t size) {
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
data = buffer[i];
|
||||
sync_send();
|
||||
serial_write_chunk(data,8);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
|
||||
static
|
||||
uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
|
||||
uint8_t pecount = 0;
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
sync_recv();
|
||||
data = serial_read_chunk(&pecount, 8);
|
||||
buffer[i] = data;
|
||||
}
|
||||
return pecount == 0;
|
||||
}
|
||||
|
||||
inline static
|
||||
void change_sender2reciver(void) {
|
||||
sync_send(); //0
|
||||
serial_delay_half1(); //1
|
||||
serial_low(); //2
|
||||
serial_input_with_pullup(); //2
|
||||
serial_delay_half1(); //3
|
||||
}
|
||||
|
||||
inline static
|
||||
void change_reciver2sender(void) {
|
||||
sync_recv(); //0
|
||||
serial_delay(); //1
|
||||
serial_low(); //3
|
||||
serial_output(); //3
|
||||
serial_delay_half1(); //4
|
||||
}
|
||||
|
||||
static inline uint8_t nibble_bits_count(uint8_t bits)
|
||||
{
|
||||
bits = (bits & 0x5) + (bits >> 1 & 0x5);
|
||||
bits = (bits & 0x3) + (bits >> 2 & 0x3);
|
||||
return bits;
|
||||
}
|
||||
|
||||
// interrupt handle to be used by the target device
|
||||
ISR(SERIAL_PIN_INTERRUPT) {
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
serial_low();
|
||||
serial_output();
|
||||
SSTD_t *trans = Transaction_table;
|
||||
#else
|
||||
// recive transaction table index
|
||||
uint8_t tid, bits;
|
||||
uint8_t pecount = 0;
|
||||
sync_recv();
|
||||
bits = serial_read_chunk(&pecount,7);
|
||||
tid = bits>>3;
|
||||
bits = (bits&7) != nibble_bits_count(tid);
|
||||
if( bits || pecount> 0 || tid > Transaction_table_size ) {
|
||||
return;
|
||||
}
|
||||
serial_delay_half1();
|
||||
|
||||
serial_high(); // response step1 low->high
|
||||
serial_output();
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH);
|
||||
SSTD_t *trans = &Transaction_table[tid];
|
||||
serial_low(); // response step2 ack high->low
|
||||
#endif
|
||||
|
||||
// target send phase
|
||||
if( trans->target2initiator_buffer_size > 0 )
|
||||
serial_send_packet((uint8_t *)trans->target2initiator_buffer,
|
||||
trans->target2initiator_buffer_size);
|
||||
// target switch to input
|
||||
change_sender2reciver();
|
||||
|
||||
// target recive phase
|
||||
if( trans->initiator2target_buffer_size > 0 ) {
|
||||
if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
|
||||
trans->initiator2target_buffer_size) ) {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
} else {
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
} else {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
}
|
||||
|
||||
sync_recv(); //weit initiator output to high
|
||||
}
|
||||
|
||||
/////////
|
||||
// start transaction by initiator
|
||||
//
|
||||
// int soft_serial_transaction(int sstd_index)
|
||||
//
|
||||
// Returns:
|
||||
// TRANSACTION_END
|
||||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
SSTD_t *trans = Transaction_table;
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
if( sstd_index > Transaction_table_size )
|
||||
return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
#endif
|
||||
cli();
|
||||
|
||||
// signal to the target that we want to start a transaction
|
||||
serial_output();
|
||||
serial_low();
|
||||
_delay_us(SLAVE_INT_WIDTH_US);
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
// wait for the target response
|
||||
serial_input_with_pullup();
|
||||
_delay_us(SLAVE_INT_RESPONSE_TIME);
|
||||
|
||||
// check if the target is present
|
||||
if (serial_read_pin()) {
|
||||
// target failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
|
||||
#else
|
||||
// send transaction table index
|
||||
int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index));
|
||||
sync_send();
|
||||
_delay_sub_us(TID_SEND_ADJUST);
|
||||
serial_write_chunk(tid, 7);
|
||||
serial_delay_half1();
|
||||
|
||||
// wait for the target response (step1 low->high)
|
||||
serial_input_with_pullup();
|
||||
while( !serial_read_pin() ) {
|
||||
_delay_sub_us(2);
|
||||
}
|
||||
|
||||
// check if the target is present (step2 high->low)
|
||||
for( int i = 0; serial_read_pin(); i++ ) {
|
||||
if (i > SLAVE_INT_ACK_WIDTH + 1) {
|
||||
// slave failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
// initiator recive phase
|
||||
// if the target is present syncronize with it
|
||||
if( trans->target2initiator_buffer_size > 0 ) {
|
||||
if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
|
||||
trans->target2initiator_buffer_size) ) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
sei();
|
||||
return TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// initiator switch to output
|
||||
change_reciver2sender();
|
||||
|
||||
// initiator send phase
|
||||
if( trans->initiator2target_buffer_size > 0 ) {
|
||||
serial_send_packet((uint8_t *)trans->initiator2target_buffer,
|
||||
trans->initiator2target_buffer_size);
|
||||
}
|
||||
|
||||
// always, release the line when not in use
|
||||
sync_send();
|
||||
|
||||
*trans->status = TRANSACTION_END;
|
||||
sei();
|
||||
return TRANSACTION_END;
|
||||
}
|
||||
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index) {
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
cli();
|
||||
int retval = *trans->status;
|
||||
*trans->status = 0;;
|
||||
sei();
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Helix serial.c history
|
||||
// 2018-1-29 fork from let's split and add PD2, modify sync_recv() (#2308, bceffdefc)
|
||||
// 2018-6-28 bug fix master to slave comm and speed up (#3255, 1038bbef4)
|
||||
// (adjusted with avr-gcc 4.9.2)
|
||||
// 2018-7-13 remove USE_SERIAL_PD2 macro (#3374, f30d6dd78)
|
||||
// (adjusted with avr-gcc 4.9.2)
|
||||
// 2018-8-11 add support multi-type transaction (#3608, feb5e4aae)
|
||||
// (adjusted with avr-gcc 4.9.2)
|
||||
// 2018-10-21 fix serial and RGB animation conflict (#4191, 4665e4fff)
|
||||
// (adjusted with avr-gcc 7.3.0)
|
||||
// 2018-10-28 re-adjust compiler depend value of delay (#4269, 8517f8a66)
|
||||
// (adjusted with avr-gcc 5.4.0, 7.3.0)
|
@ -0,0 +1,84 @@
|
||||
#ifndef SOFT_SERIAL_H
|
||||
#define SOFT_SERIAL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Need Soft Serial defines in config.h
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// ex.
|
||||
// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
|
||||
// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
|
||||
// // 1: about 137kbps (default)
|
||||
// // 2: about 75kbps
|
||||
// // 3: about 39kbps
|
||||
// // 4: about 26kbps
|
||||
// // 5: about 20kbps
|
||||
//
|
||||
// //// USE Simple API (OLD API, compatible with let's split serial.c)
|
||||
// ex.
|
||||
// #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
// #define SERIAL_MASTER_BUFFER_LENGTH 1
|
||||
//
|
||||
// //// USE flexible API (using multi-type transaction function)
|
||||
// #define SERIAL_USE_MULTI_TRANSACTION
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
/* --- USE Simple API (OLD API, compatible with let's split serial.c) */
|
||||
#if SERIAL_SLAVE_BUFFER_LENGTH > 0
|
||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||
#endif
|
||||
#if SERIAL_MASTER_BUFFER_LENGTH > 0
|
||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||
#endif
|
||||
|
||||
void serial_master_init(void);
|
||||
void serial_slave_init(void);
|
||||
int serial_update_buffers(void);
|
||||
|
||||
#endif // USE Simple API
|
||||
|
||||
// Soft Serial Transaction Descriptor
|
||||
typedef struct _SSTD_t {
|
||||
uint8_t *status;
|
||||
uint8_t initiator2target_buffer_size;
|
||||
uint8_t *initiator2target_buffer;
|
||||
uint8_t target2initiator_buffer_size;
|
||||
uint8_t *target2initiator_buffer;
|
||||
} SSTD_t;
|
||||
#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t))
|
||||
|
||||
// initiator is transaction start side
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
// target is interrupt accept side
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
|
||||
// initiator resullt
|
||||
#define TRANSACTION_END 0
|
||||
#define TRANSACTION_NO_RESPONSE 0x1
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void);
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
#endif
|
||||
|
||||
// target status
|
||||
// *SSTD_t.status has
|
||||
// initiator:
|
||||
// TRANSACTION_END
|
||||
// or TRANSACTION_NO_RESPONSE
|
||||
// or TRANSACTION_DATA_ERROR
|
||||
// target:
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// or TRANSACTION_ACCEPTED
|
||||
#define TRANSACTION_ACCEPTED 0x8
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
#endif
|
||||
|
||||
#endif /* SOFT_SERIAL_H */
|
@ -0,0 +1,346 @@
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
#include "ssd1306.h"
|
||||
#include "i2c.h"
|
||||
#include <string.h>
|
||||
#include "print.h"
|
||||
#ifdef ADAFRUIT_BLE_ENABLE
|
||||
#include "adafruit_ble.h"
|
||||
#endif
|
||||
#ifdef PROTOCOL_LUFA
|
||||
#include "lufa.h"
|
||||
#endif
|
||||
#include "sendchar.h"
|
||||
#include "timer.h"
|
||||
|
||||
static const unsigned char font[] PROGMEM;
|
||||
|
||||
// Set this to 1 to help diagnose early startup problems
|
||||
// when testing power-on with ble. Turn it off otherwise,
|
||||
// as the latency of printing most of the debug info messes
|
||||
// with the matrix scan, causing keys to drop.
|
||||
#define DEBUG_TO_SCREEN 0
|
||||
|
||||
//static uint16_t last_battery_update;
|
||||
//static uint32_t vbat;
|
||||
//#define BatteryUpdateInterval 10000 /* milliseconds */
|
||||
|
||||
// 'last_flush' is declared as uint16_t,
|
||||
// so this must be less than 65535
|
||||
#define ScreenOffInterval 60000 /* milliseconds */
|
||||
#if DEBUG_TO_SCREEN
|
||||
static uint8_t displaying;
|
||||
#endif
|
||||
static uint16_t last_flush;
|
||||
|
||||
static bool force_dirty = true;
|
||||
|
||||
// Write command sequence.
|
||||
// Returns true on success.
|
||||
static inline bool _send_cmd1(uint8_t cmd) {
|
||||
bool res = false;
|
||||
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (i2c_master_write(0x0 /* command byte follows */)) {
|
||||
print("failed to write control byte\n");
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (i2c_master_write(cmd)) {
|
||||
xprintf("failed to write command %d\n", cmd);
|
||||
goto done;
|
||||
}
|
||||
res = true;
|
||||
done:
|
||||
i2c_master_stop();
|
||||
return res;
|
||||
}
|
||||
|
||||
// Write 2-byte command sequence.
|
||||
// Returns true on success
|
||||
static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
|
||||
if (!_send_cmd1(cmd)) {
|
||||
return false;
|
||||
}
|
||||
return _send_cmd1(opr);
|
||||
}
|
||||
|
||||
// Write 3-byte command sequence.
|
||||
// Returns true on success
|
||||
static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
|
||||
if (!_send_cmd1(cmd)) {
|
||||
return false;
|
||||
}
|
||||
if (!_send_cmd1(opr1)) {
|
||||
return false;
|
||||
}
|
||||
return _send_cmd1(opr2);
|
||||
}
|
||||
|
||||
#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
|
||||
#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
|
||||
#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
|
||||
|
||||
static void clear_display(void) {
|
||||
matrix_clear(&display);
|
||||
|
||||
// Clear all of the display bits (there can be random noise
|
||||
// in the RAM on startup)
|
||||
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
|
||||
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
|
||||
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
goto done;
|
||||
}
|
||||
if (i2c_master_write(0x40)) {
|
||||
// Data mode
|
||||
goto done;
|
||||
}
|
||||
for (uint8_t row = 0; row < MatrixRows; ++row) {
|
||||
for (uint8_t col = 0; col < DisplayWidth; ++col) {
|
||||
i2c_master_write(0);
|
||||
}
|
||||
}
|
||||
|
||||
display.dirty = false;
|
||||
|
||||
done:
|
||||
i2c_master_stop();
|
||||
}
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
#undef sendchar
|
||||
static int8_t capture_sendchar(uint8_t c) {
|
||||
sendchar(c);
|
||||
iota_gfx_write_char(c);
|
||||
|
||||
if (!displaying) {
|
||||
iota_gfx_flush();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool iota_gfx_init(bool rotate) {
|
||||
bool success = false;
|
||||
|
||||
i2c_master_init();
|
||||
send_cmd1(DisplayOff);
|
||||
send_cmd2(SetDisplayClockDiv, 0x80);
|
||||
send_cmd2(SetMultiPlex, DisplayHeight - 1);
|
||||
|
||||
send_cmd2(SetDisplayOffset, 0);
|
||||
|
||||
|
||||
send_cmd1(SetStartLine | 0x0);
|
||||
send_cmd2(SetChargePump, 0x14 /* Enable */);
|
||||
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
|
||||
|
||||
if(rotate){
|
||||
// the following Flip the display orientation 180 degrees
|
||||
send_cmd1(SegRemap);
|
||||
send_cmd1(ComScanInc);
|
||||
}else{
|
||||
// Flips the display orientation 0 degrees
|
||||
send_cmd1(SegRemap | 0x1);
|
||||
send_cmd1(ComScanDec);
|
||||
}
|
||||
|
||||
send_cmd2(SetComPins, 0x2);
|
||||
send_cmd2(SetContrast, 0x8f);
|
||||
send_cmd2(SetPreCharge, 0xf1);
|
||||
send_cmd2(SetVComDetect, 0x40);
|
||||
send_cmd1(DisplayAllOnResume);
|
||||
send_cmd1(NormalDisplay);
|
||||
send_cmd1(DeActivateScroll);
|
||||
send_cmd1(DisplayOn);
|
||||
|
||||
send_cmd2(SetContrast, 0); // Dim
|
||||
|
||||
clear_display();
|
||||
|
||||
success = true;
|
||||
|
||||
iota_gfx_flush();
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
print_set_sendchar(capture_sendchar);
|
||||
#endif
|
||||
|
||||
done:
|
||||
return success;
|
||||
}
|
||||
|
||||
bool iota_gfx_off(void) {
|
||||
bool success = false;
|
||||
|
||||
send_cmd1(DisplayOff);
|
||||
success = true;
|
||||
|
||||
done:
|
||||
return success;
|
||||
}
|
||||
|
||||
bool iota_gfx_on(void) {
|
||||
bool success = false;
|
||||
|
||||
send_cmd1(DisplayOn);
|
||||
success = true;
|
||||
|
||||
done:
|
||||
return success;
|
||||
}
|
||||
|
||||
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
|
||||
*matrix->cursor = c;
|
||||
++matrix->cursor;
|
||||
|
||||
if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
|
||||
// We went off the end; scroll the display upwards by one line
|
||||
memmove(&matrix->display[0], &matrix->display[1],
|
||||
MatrixCols * (MatrixRows - 1));
|
||||
matrix->cursor = &matrix->display[MatrixRows - 1][0];
|
||||
memset(matrix->cursor, ' ', MatrixCols);
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
|
||||
matrix->dirty = true;
|
||||
|
||||
if (c == '\n') {
|
||||
// Clear to end of line from the cursor and then move to the
|
||||
// start of the next line
|
||||
uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
|
||||
|
||||
while (cursor_col++ < MatrixCols) {
|
||||
matrix_write_char_inner(matrix, ' ');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
matrix_write_char_inner(matrix, c);
|
||||
}
|
||||
|
||||
void iota_gfx_write_char(uint8_t c) {
|
||||
matrix_write_char(&display, c);
|
||||
}
|
||||
|
||||
void matrix_write(struct CharacterMatrix *matrix, const char *data) {
|
||||
const char *end = data + strlen(data);
|
||||
while (data < end) {
|
||||
matrix_write_char(matrix, *data);
|
||||
++data;
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) {
|
||||
char data_ln[strlen(data)+2];
|
||||
snprintf(data_ln, sizeof(data_ln), "%s\n", data);
|
||||
matrix_write(matrix, data_ln);
|
||||
}
|
||||
|
||||
void iota_gfx_write(const char *data) {
|
||||
matrix_write(&display, data);
|
||||
}
|
||||
|
||||
void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
|
||||
while (true) {
|
||||
uint8_t c = pgm_read_byte(data);
|
||||
if (c == 0) {
|
||||
return;
|
||||
}
|
||||
matrix_write_char(matrix, c);
|
||||
++data;
|
||||
}
|
||||
}
|
||||
|
||||
void iota_gfx_write_P(const char *data) {
|
||||
matrix_write_P(&display, data);
|
||||
}
|
||||
|
||||
void matrix_clear(struct CharacterMatrix *matrix) {
|
||||
memset(matrix->display, ' ', sizeof(matrix->display));
|
||||
matrix->cursor = &matrix->display[0][0];
|
||||
matrix->dirty = true;
|
||||
}
|
||||
|
||||
void iota_gfx_clear_screen(void) {
|
||||
matrix_clear(&display);
|
||||
}
|
||||
|
||||
void matrix_render(struct CharacterMatrix *matrix) {
|
||||
last_flush = timer_read();
|
||||
iota_gfx_on();
|
||||
#if DEBUG_TO_SCREEN
|
||||
++displaying;
|
||||
#endif
|
||||
|
||||
// Move to the home position
|
||||
send_cmd3(PageAddr, 0, MatrixRows - 1);
|
||||
send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
|
||||
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
goto done;
|
||||
}
|
||||
if (i2c_master_write(0x40)) {
|
||||
// Data mode
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (uint8_t row = 0; row < MatrixRows; ++row) {
|
||||
for (uint8_t col = 0; col < MatrixCols; ++col) {
|
||||
const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth);
|
||||
|
||||
for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) {
|
||||
uint8_t colBits = pgm_read_byte(glyph + glyphCol);
|
||||
i2c_master_write(colBits);
|
||||
}
|
||||
|
||||
// 1 column of space between chars (it's not included in the glyph)
|
||||
//i2c_master_write(0);
|
||||
}
|
||||
}
|
||||
|
||||
matrix->dirty = false;
|
||||
|
||||
done:
|
||||
i2c_master_stop();
|
||||
#if DEBUG_TO_SCREEN
|
||||
--displaying;
|
||||
#endif
|
||||
}
|
||||
|
||||
void iota_gfx_flush(void) {
|
||||
matrix_render(&display);
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void iota_gfx_task_user(void) {
|
||||
}
|
||||
|
||||
void iota_gfx_task(void) {
|
||||
iota_gfx_task_user();
|
||||
|
||||
if (display.dirty|| force_dirty) {
|
||||
iota_gfx_flush();
|
||||
force_dirty = false;
|
||||
}
|
||||
|
||||
/*
|
||||
if (timer_elapsed(last_flush) > ScreenOffInterval) {
|
||||
iota_gfx_off();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
bool process_record_gfx(uint16_t keycode, keyrecord_t *record) {
|
||||
force_dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "pincontrol.h"
|
||||
#include "action.h"
|
||||
|
||||
enum ssd1306_cmds {
|
||||
DisplayOff = 0xAE,
|
||||
DisplayOn = 0xAF,
|
||||
|
||||
SetContrast = 0x81,
|
||||
DisplayAllOnResume = 0xA4,
|
||||
|
||||
DisplayAllOn = 0xA5,
|
||||
NormalDisplay = 0xA6,
|
||||
InvertDisplay = 0xA7,
|
||||
SetDisplayOffset = 0xD3,
|
||||
SetComPins = 0xda,
|
||||
SetVComDetect = 0xdb,
|
||||
SetDisplayClockDiv = 0xD5,
|
||||
SetPreCharge = 0xd9,
|
||||
SetMultiPlex = 0xa8,
|
||||
SetLowColumn = 0x00,
|
||||
SetHighColumn = 0x10,
|
||||
SetStartLine = 0x40,
|
||||
|
||||
SetMemoryMode = 0x20,
|
||||
ColumnAddr = 0x21,
|
||||
PageAddr = 0x22,
|
||||
|
||||
ComScanInc = 0xc0,
|
||||
ComScanDec = 0xc8,
|
||||
SegRemap = 0xa0,
|
||||
SetChargePump = 0x8d,
|
||||
ExternalVcc = 0x01,
|
||||
SwitchCapVcc = 0x02,
|
||||
|
||||
ActivateScroll = 0x2f,
|
||||
DeActivateScroll = 0x2e,
|
||||
SetVerticalScrollArea = 0xa3,
|
||||
RightHorizontalScroll = 0x26,
|
||||
LeftHorizontalScroll = 0x27,
|
||||
VerticalAndRightHorizontalScroll = 0x29,
|
||||
VerticalAndLeftHorizontalScroll = 0x2a,
|
||||
};
|
||||
|
||||
// Controls the SSD1306 128x32 OLED display via i2c
|
||||
|
||||
#ifndef SSD1306_ADDRESS
|
||||
#define SSD1306_ADDRESS 0x3C
|
||||
#endif
|
||||
|
||||
#define DisplayHeight 32
|
||||
#define DisplayWidth 128
|
||||
|
||||
#define FontHeight 8
|
||||
#define FontWidth 6
|
||||
|
||||
#define MatrixRows (DisplayHeight / FontHeight)
|
||||
#define MatrixCols (DisplayWidth / FontWidth)
|
||||
|
||||
struct CharacterMatrix {
|
||||
uint8_t display[MatrixRows][MatrixCols];
|
||||
uint8_t *cursor;
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
struct CharacterMatrix display;
|
||||
|
||||
bool iota_gfx_init(bool rotate);
|
||||
void iota_gfx_task(void);
|
||||
bool iota_gfx_off(void);
|
||||
bool iota_gfx_on(void);
|
||||
void iota_gfx_flush(void);
|
||||
void iota_gfx_write_char(uint8_t c);
|
||||
void iota_gfx_write(const char *data);
|
||||
void iota_gfx_write_P(const char *data);
|
||||
void iota_gfx_clear_screen(void);
|
||||
|
||||
void iota_gfx_task_user(void);
|
||||
|
||||
void matrix_clear(struct CharacterMatrix *matrix);
|
||||
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c);
|
||||
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c);
|
||||
void matrix_write(struct CharacterMatrix *matrix, const char *data);
|
||||
void matrix_write_ln(struct CharacterMatrix *matrix, const char *data);
|
||||
void matrix_write_P(struct CharacterMatrix *matrix, const char *data);
|
||||
void matrix_render(struct CharacterMatrix *matrix);
|
||||
|
||||
bool process_record_gfx(uint16_t keycode, keyrecord_t *record);
|
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0xD070
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER Backprop Studio
|
||||
#define PRODUCT Doro67 Multi PCB
|
||||
#define DESCRIPTION 65% custom keyboard
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 5
|
||||
#define MATRIX_COLS 15
|
||||
|
||||
/*
|
||||
* Keyboard Matrix Assignments
|
||||
*
|
||||
* Change this to how you wired your keyboard
|
||||
* COLS: AVR pins used for columns, left to right
|
||||
* ROWS: AVR pins used for rows, top to bottom
|
||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||
*
|
||||
*/
|
||||
#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 }
|
||||
#define MATRIX_COL_PINS { B0, B1, B2, B3, D4, D6, D7, B4, B5, B6, C6, C7, F5, F6, F7 }
|
||||
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
#define BACKLIGHT_LEVELS 7
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"keyboard_name": "Doro67 Multi PCB",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"width": 16,
|
||||
"height": 5,
|
||||
"layouts": {
|
||||
"LAYOUT_ansi": {
|
||||
"layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Ins", "x":15, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Del", "x":15, "y":1}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"PgUp", "x":15, "y":2}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"Up", "x":14, "y":3}, {"label":"PgDn", "x":15, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"MO(1)", "x":11.25, "y":4, "w":1.25}, {"label":"Left", "x":13, "y":4}, {"label":"Down", "x":14, "y":4}, {"label":"Right", "x":15, "y":4}]
|
||||
},
|
||||
"LAYOUT_iso": {
|
||||
"layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"\"", "x":2, "y":0}, {"label":"\u00a3", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Ins", "x":15, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"Enter", "x":13.75, "y":1, "w":1.25, "h":2}, {"label":"Del", "x":15, "y":1}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"@", "x":11.75, "y":2}, {"label":"~", "x":12.75, "y":2}, {"label":"PgUp", "x":15, "y":2}, {"label":"Shift", "x":0, "y":3, "w":1.25}, {"label":"|", "x":1.25, "y":3}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"Up", "x":14, "y":3}, {"label":"PgDn", "x":15, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"MO(1)", "x":11.25, "y":4, "w":1.25}, {"label":"Left", "x":13, "y":4}, {"label":"Down", "x":14, "y":4}, {"label":"Right", "x":15, "y":4}]
|
||||
},
|
||||
"LAYOUT_multi": {
|
||||
"layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Back", "x":13, "y":0}, {"label":"F2", "x":14, "y":0}, {"label":"Ins", "x":15, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Del", "x":15, "y":1}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"PgUp", "x":15, "y":2}, {"label":"Shift", "x":0, "y":3, "w":1.25}, {"label":"F1", "x":1.25, "y":3}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"Up", "x":14, "y":3}, {"label":"PgDn", "x":15, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":2.75}, {"x":6.5, "y":4, "w":1.25}, {"x":7.75, "y":4, "w":2.25}, {"label":"Alt", "x":10, "y":4}, {"label":"MO(1)", "x":11, "y":4}, {"label":"Ctrl", "x":12, "y":4}, {"label":"Left", "x":13, "y":4}, {"label":"Down", "x":14, "y":4}, {"label":"Right", "x":15, "y":4}]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/* Copyright 2019 ShadeDream
|
||||
*
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT_ansi(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_UP, KC_PGDN,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_LALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
|
||||
),
|
||||
[1] = LAYOUT_ansi(
|
||||
KC_GRV, 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_TRNS, KC_TRNS,
|
||||
BL_TOGG, BL_STEP, BL_DEC, BL_INC, 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_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
|
||||
),
|
||||
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
# Default Doro67 ANSI layout.
|
||||
|
||||
This is the default ANSI layout that comes flashed on the Doro67 multi PCB with
|
||||
the exception of adding backtick as it was not mapped.
|
||||
|
||||
Default Layer:
|
||||
|
||||
```
|
||||
,---------------------------------------------------------------.
|
||||
|Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|BackSp |Ins|
|
||||
|---------------------------------------------------------------|
|
||||
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |Del|
|
||||
|---------------------------------------------------------------|
|
||||
|Ctrl | A| S| D| F| G| H| J| K| L| ;| '| Enter |PUp|
|
||||
|---------------------------------------------------------------|
|
||||
|Shift | Z| X| C| V| B| N| M| ,| .| /| Shift| Up|PDn|
|
||||
|---------------------------------------------------------------|
|
||||
|Ctrl |GUI |Alt | Space |Alt |FN |Lft|Dwn|Rgt|
|
||||
`---------------------------------------------------------------'
|
||||
```
|
||||
|
||||
FN Layer:
|
||||
|
||||
```
|
||||
,---------------------------------------------------------------.
|
||||
|` | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| | |
|
||||
|---------------------------------------------------------------|
|
||||
|BLTog|Stp|Dec|Inc| | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | |
|
||||
`---------------------------------------------------------------'
|
||||
```
|
@ -0,0 +1,36 @@
|
||||
/* Copyright 2019 ShadeDream
|
||||
*
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT_iso(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS,
|
||||
KC_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_ENT, KC_DEL,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_PGUP,
|
||||
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_UP, KC_PGDN,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_LALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
|
||||
),
|
||||
[1] = LAYOUT_iso(
|
||||
KC_GRV, 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_TRNS, KC_TRNS,
|
||||
BL_TOGG, BL_STEP, BL_DEC, BL_INC, 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_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
|
||||
),
|
||||
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
# Default Doro67 ISO layout.
|
||||
|
||||
This is the default ISO layout that comes flashed on the Doro67 multi PCB with
|
||||
the exception of adding backtick and UK ISO specific keycodes as they were not mapped.
|
||||
|
||||
Default Layer:
|
||||
|
||||
```
|
||||
,---------------------------------------------------------------.
|
||||
|Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|BackSp |Ins|
|
||||
|---------------------------------------------------------------|
|
||||
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| |Del|
|
||||
|------------------------------------------------------|Entr|---|
|
||||
|Ctrl | A| S| D| F| G| H| J| K| L| ;| '| #| |PUp|
|
||||
|---------------------------------------------------------------|
|
||||
|Shft| \| Z| X| C| V| B| N| M| ,| .| /| Shift| Up|PDn|
|
||||
|---------------------------------------------------------------|
|
||||
|Ctrl |GUI |Alt | Space |Alt |FN |Lft|Dwn|Rgt|
|
||||
`---------------------------------------------------------------'
|
||||
```
|
||||
|
||||
FN Layer:
|
||||
|
||||
```
|
||||
,---------------------------------------------------------------.
|
||||
|` | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| | |
|
||||
|---------------------------------------------------------------|
|
||||
|BLTog|Stp|Dec|Inc| | | | | | | | | | | |
|
||||
|------------------------------------------------------| |---|
|
||||
| | | | | | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | |
|
||||
`---------------------------------------------------------------'
|
||||
```
|
@ -0,0 +1,36 @@
|
||||
/* Copyright 2019 ShadeDream
|
||||
*
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT_multi(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_F2, KC_INS,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,
|
||||
KC_LSFT, KC_F1, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
|
||||
),
|
||||
[1] = LAYOUT_multi(
|
||||
KC_GRV, 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_TRNS, KC_TRNS, KC_TRNS,
|
||||
BL_TOGG, BL_STEP, BL_DEC, BL_INC, 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_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
|
||||
),
|
||||
|
||||
};
|
@ -0,0 +1,39 @@
|
||||
# Default Doro67 Multi layout.
|
||||
|
||||
This is the default Multi layout that comes flashed on the Doro67 multi PCB with
|
||||
the exception of adding backtick as it was not mapped.
|
||||
|
||||
This layout supports both the blocker and non-blocker layouts (2 & 4) with the
|
||||
difference that the blocker layout lacks the right control key.
|
||||
|
||||
Default Layer:
|
||||
|
||||
```
|
||||
,---------------------------------------------------------------.
|
||||
|Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| BS| F2|Ins|
|
||||
|---------------------------------------------------------------|
|
||||
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |Del|
|
||||
|---------------------------------------------------------------|
|
||||
|Ctrl | A| S| D| F| G| H| J| K| L| ;| '| Enter |PUp|
|
||||
|---------------------------------------------------------------|
|
||||
|Shft| F1| Z| X| C| V| B| N| M| ,| .| /| Shift| Up|PDn|
|
||||
|---------------------------------------------------------------|
|
||||
|Ctrl |GUI |Alt | Space |Space| Space |Alt|MO1|Ctl|Lft|Dwn|Rgt|
|
||||
`---------------------------------------------------------------'
|
||||
```
|
||||
|
||||
FN Layer:
|
||||
|
||||
```
|
||||
,---------------------------------------------------------------.
|
||||
|` | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| | |
|
||||
|---------------------------------------------------------------|
|
||||
|BLTog|Stp|Dec|Inc| | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | | | | | | | |
|
||||
|---------------------------------------------------------------|
|
||||
| | | | | | | | | | | | |
|
||||
`---------------------------------------------------------------'
|
||||
```
|
@ -0,0 +1,43 @@
|
||||
/* Copyright 2019 ShadeDream
|
||||
*
|
||||
* 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 "multi.h"
|
||||
|
||||
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
|
||||
|
||||
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,59 @@
|
||||
/* Copyright 2019 ShadeDream
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define LAYOUT_ansi( \
|
||||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \
|
||||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
|
||||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, K2E, \
|
||||
K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \
|
||||
K40, K41, K42, K44, K49, K4A, K4C, K4D, K4E \
|
||||
) { \
|
||||
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \
|
||||
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \
|
||||
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D, K2E }, \
|
||||
{ K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \
|
||||
{ K40, K41, K42, KC_NO, K44, KC_NO, KC_NO, KC_NO, KC_NO, K49, K4A, KC_NO, K4C, K4D, K4E }, \
|
||||
}
|
||||
|
||||
#define LAYOUT_iso( \
|
||||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \
|
||||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
|
||||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, K2E, \
|
||||
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \
|
||||
K40, K41, K42, K44, K49, K4A, K4C, K4D, K4E \
|
||||
) { \
|
||||
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \
|
||||
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \
|
||||
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D, K2E }, \
|
||||
{ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \
|
||||
{ K40, K41, K42, KC_NO, K44, KC_NO, KC_NO, KC_NO, KC_NO, K49, K4A, KC_NO, K4C, K4D, K4E }, \
|
||||
}
|
||||
|
||||
#define LAYOUT_multi( \
|
||||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K48, K0E, \
|
||||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
|
||||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, K2E, \
|
||||
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \
|
||||
K40, K41, K42, K43, K44, K45, K49, K4A, K4B, K4C, K4D, K4E \
|
||||
) { \
|
||||
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \
|
||||
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \
|
||||
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D, K2E }, \
|
||||
{ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \
|
||||
{ K40, K41, K42, K43, K44, K45, KC_NO, KC_NO, K48, K49, K4A, K4B, K4C, K4D, K4E }, \
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
Doro67 Multi PCB
|
||||
===
|
||||
|
||||
A custom 65% keyboard with multiple layout support.
|
||||
|
||||
Do not flash RGB firmware for this board.
|
||||
|
||||
Keyboard Maintainer: [ShadeDream](https://github.com/shadedream)
|
||||
Hardware Supported: Doro67 Multi PCB
|
||||
Hardware Availability: [Geekhack GB](https://geekhack.org/index.php?topic=97265.0)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make doro67/multi:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
@ -0,0 +1,47 @@
|
||||
MCU = atmega32u4
|
||||
F_CPU = 16000000
|
||||
ARCH = AVR8
|
||||
F_USB = $(F_CPU)
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
|
||||
# Bootloader selection
|
||||
# Teensy halfkay
|
||||
# Pro Micro caterina
|
||||
# Atmel DFU atmel-dfu
|
||||
# LUFA DFU lufa-dfu
|
||||
# QMK DFU qmk-dfu
|
||||
# atmega32a bootloadHID
|
||||
BOOTLOADER = atmel-dfu
|
||||
|
||||
|
||||
# If you don't know the bootloader type, then you can specify the
|
||||
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
# OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = yes # Console for debug(+400)
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
# 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 = no # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality on B7 by default
|
||||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||
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
|
||||
HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400)
|
@ -0,0 +1,7 @@
|
||||
#include <avr/io.h>
|
||||
#include "duck_led.h"
|
||||
#include "quantum.h"
|
||||
|
||||
void show(void) {
|
||||
wait_us((RES / 1000UL) + 1);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#define RES 6000
|
||||
|
||||
#define NS_PER_SEC (1000000000L)
|
||||
#define CYCLES_PER_SEC (F_CPU)
|
||||
#define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC)
|
||||
#define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE)
|
||||
|
||||
enum Device {
|
||||
Device_PCBRGB,
|
||||
Device_STATUSLED
|
||||
};
|
||||
|
||||
void show(void);
|
||||
|
@ -1,11 +1,7 @@
|
||||
enum Device {
|
||||
Device_PCBRGB,
|
||||
Device_STATUSLED
|
||||
};
|
||||
#include "duck_led/duck_led.h"
|
||||
|
||||
void indicator_leds_set(bool leds[8]);
|
||||
void backlight_toggle_rgb(bool enabled);
|
||||
void backlight_set_rgb(uint8_t cfg[17][3]);
|
||||
void backlight_init_ports(void);
|
||||
void send_color(uint8_t r, uint8_t g, uint8_t b, enum Device device);
|
||||
void show(void);
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Copy and worked on with love from the EZ team
|
||||
|
||||
#pragma once
|
||||
#include "config_common.h"
|
||||
|
||||
#define VERBOSE
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x1337
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER g Heavy Industries
|
||||
#define PRODUCT ErgoTaco
|
||||
#define DESCRIPTION QMK keyboard firmware for ErgoTaco
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 12
|
||||
#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
|
||||
#define MATRIX_COLS 1
|
||||
|
||||
#define MOUSEKEY_INTERVAL 20
|
||||
#define MOUSEKEY_DELAY 0
|
||||
#define MOUSEKEY_TIME_TO_MAX 60
|
||||
#define MOUSEKEY_MAX_SPEED 7
|
||||
#define MOUSEKEY_WHEEL_DELAY 0
|
||||
#define TAPPING_TOGGLE 1
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
#define TAPPING_TERM 200
|
||||
#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.)
|
||||
|
||||
/* 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() (get_mods() == MOD_MASK_CTRL || get_mods() == MOD_MASK_SHIFT)
|
||||
|
||||
#define DEBOUNCE 5
|
||||
#define USB_MAX_POWER_CONSUMPTION 500
|
@ -0,0 +1,72 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
bool i2c_initialized = 0;
|
||||
i2c_status_t mcp23018_status = 0x20;
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
// (tied to Vcc for hardware convenience)
|
||||
//DDRB &= ~(1<<4); // set B(4) as input
|
||||
//PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
|
||||
|
||||
// unused pins
|
||||
// set as input with internal pull-up enabled
|
||||
DDRB &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
|
||||
PORTB |= (1<<4 | 1<<5 | 1<<6 | 1<<7);
|
||||
|
||||
DDRC &= ~(1<<7 | 1<<6);
|
||||
PORTC |= (1<<7 | 1<<6);
|
||||
|
||||
DDRD &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
|
||||
PORTD |= (1<<4 | 1<<5 | 1<<6 | 1<<7);
|
||||
|
||||
DDRE &= ~(1<<6);
|
||||
PORTE |= (1<<6);
|
||||
|
||||
DDRF &= ~(1<<0 | 1<<1 | 1<<4 | 1<<6 | 1<<7);
|
||||
PORTF |= (1<<0 | 1<<1 | 1<<4 | 1<<6 | 1<<7);
|
||||
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
|
||||
uint8_t init_mcp23018(void) {
|
||||
print("starting init");
|
||||
mcp23018_status = 0x20;
|
||||
|
||||
// I2C subsystem
|
||||
|
||||
// uint8_t sreg_prev;
|
||||
// sreg_prev=SREG;
|
||||
// cli();
|
||||
|
||||
if (i2c_initialized == 0) {
|
||||
i2c_init(); // on pins D(1,0)
|
||||
i2c_initialized = true;
|
||||
_delay_ms(1000);
|
||||
}
|
||||
|
||||
// set pin direction
|
||||
// - unused : input : 1
|
||||
// - input : input : 1
|
||||
// - driving : output : 0
|
||||
mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
i2c_stop();
|
||||
|
||||
// set pull-up
|
||||
// - unused : on : 1
|
||||
// - input : on : 1
|
||||
// - driving : off : 0
|
||||
mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
|
||||
out:
|
||||
i2c_stop();
|
||||
// SREG=sreg_prev;
|
||||
//uprintf("Init %x\n", mcp23018_status);
|
||||
return mcp23018_status;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include <util/delay.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "quantum.h"
|
||||
#include "i2c_master.h"
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
extern i2c_status_t mcp23018_status;
|
||||
#define ERGODOX_EZ_I2C_TIMEOUT 1000
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
#define CPU_16MHz 0x00
|
||||
|
||||
// I2C aliases and register addresses (see "mcp23018.md")
|
||||
//#define I2C_ADDR 0b0100000
|
||||
#define I2C_ADDR 0x20
|
||||
#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE )
|
||||
#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ )
|
||||
#define IODIRA 0x00 // i/o direction register
|
||||
#define IODIRB 0x01
|
||||
#define GPPUA 0x0C // GPIO pull-up resistor register
|
||||
#define GPPUB 0x0D
|
||||
#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
|
||||
#define GPIOB 0x13
|
||||
#define OLATA 0x14 // output latch register
|
||||
#define OLATB 0x15
|
||||
|
||||
void init_ergodox(void);
|
||||
uint8_t init_mcp23018(void);
|
||||
|
||||
/* ---------- LEFT HAND ----------- ---------- RIGHT HAND ---------- */
|
||||
#define LAYOUT( \
|
||||
L00,L01,L02,L03,L04,L05, R00,R01,R02,R03,R04,R05) \
|
||||
\
|
||||
/* matrix positions */ \
|
||||
{ \
|
||||
{R00}, \
|
||||
{R01}, \
|
||||
{R02}, \
|
||||
{R03}, \
|
||||
{R04}, \
|
||||
{R05}, \
|
||||
{L05}, \
|
||||
{L04}, \
|
||||
{L03}, \
|
||||
{L02}, \
|
||||
{L01}, \
|
||||
{L00}, \
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
{
|
||||
"keyboard_name": "ErgoTaco",
|
||||
"url": "http://gboards.ca",
|
||||
"maintainer": "germ",
|
||||
"width": 13,
|
||||
"height": 2.75,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [
|
||||
{
|
||||
"x": 0,
|
||||
"y": 1.25
|
||||
},
|
||||
{
|
||||
"x": 1,
|
||||
"y": 0.75
|
||||
},
|
||||
{
|
||||
"x": 2,
|
||||
"y": 0.5
|
||||
},
|
||||
{
|
||||
"x": 3,
|
||||
"y": 0.25
|
||||
},
|
||||
{
|
||||
"x": 4,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": 5,
|
||||
"y": 1.75
|
||||
},
|
||||
{
|
||||
"x": 7,
|
||||
"y": 1.75
|
||||
},
|
||||
{
|
||||
"x": 8,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"x": 9,
|
||||
"y": 0.25
|
||||
},
|
||||
{
|
||||
"x": 10,
|
||||
"y": 0.5
|
||||
},
|
||||
{
|
||||
"x": 11,
|
||||
"y": 0.75
|
||||
},
|
||||
{
|
||||
"x": 12,
|
||||
"y": 1.25
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/* Good on you for modifying your layout! if you don't have
|
||||
* time to read the QMK docs, a list of keycodes can be found at
|
||||
*
|
||||
* https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md
|
||||
*
|
||||
* There's also a template for adding new layers at the bottom of this file!
|
||||
*/
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
#define FIESTA 0 // default layer
|
||||
#define TACOTIME 1 // symbols
|
||||
|
||||
// Blank template at the bottom
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Keymap template
|
||||
*
|
||||
* ,-------------------------------------------------. ,--------------------------------------------.
|
||||
* | | | | | | | | | | | | | | |
|
||||
* `-------+------+------+------+------+-------------' `-------+------+------+------+------+--------' */
|
||||
[FIESTA] = LAYOUT(
|
||||
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H
|
||||
),
|
||||
};
|
||||
|
||||
/* Keymap template
|
||||
*
|
||||
* ,-------------------------------------------------. ,--------------------------------------------.
|
||||
* | | | | | | | | | | | | | | |
|
||||
* `-------+------+------+------+------+-------------' `-------+------+------+------+------+--------'
|
||||
[FIESTA] = LAYOUT(
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
|
||||
),
|
||||
*/
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void matrix_init_user(void) {
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void matrix_scan_user(void) {
|
||||
};
|
@ -0,0 +1,6 @@
|
||||
This is the default keymap for the ErgoTaco, Make it your own!
|
||||
|
||||
## Settings
|
||||
To edit various settings, enable the 1u trackball and whatnot please modify /keyboards/ergotaco/keymaps/default/rules.mk
|
||||
|
||||
Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!
|
@ -0,0 +1,10 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# make ergotaco:default:dfu
|
||||
# Make sure you have dfu-programmer installed!
|
||||
#----------------------------------------------------------------------------
|
||||
# Firmware options
|
||||
|
||||
#Debug options
|
||||
VERBOSE = yes
|
||||
DEBUG_MATRIX_SCAN_RATE = no
|
||||
DEBUG_MATRIX = yes
|
@ -0,0 +1,366 @@
|
||||
/*
|
||||
Note for ErgoDox EZ customizers: Here be dragons!
|
||||
This is not a file you want to be messing with.
|
||||
All of the interesting stuff for you is under keymaps/ :)
|
||||
Love, Erez
|
||||
|
||||
Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "matrix.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include "wait.h"
|
||||
#include "action_layer.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
#ifdef DEBUG_MATRIX_SCAN_RATE
|
||||
#include "timer.h"
|
||||
#endif
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 5
|
||||
#endif
|
||||
|
||||
// ATmega pin defs
|
||||
#define ROW1 (1<<5)
|
||||
#define COL6 (1<<0)
|
||||
#define COL7 (1<<1)
|
||||
#define COL8 (1<<2)
|
||||
#define COL9 (1<<3)
|
||||
#define COL10 (1<<2)
|
||||
#define COL11 (1<<3)
|
||||
|
||||
|
||||
// bit masks
|
||||
#define BMASK (COL7 | COL8 | COL9 | COL6)
|
||||
#define DMASK (COL10 | COL11)
|
||||
#define FMASK (ROW1)
|
||||
|
||||
/* matrix state(1:on, 0:off) */
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
/*
|
||||
* matrix state(1:on, 0:off)
|
||||
* contains the raw values without debounce filtering of the last read cycle.
|
||||
*/
|
||||
static matrix_row_t raw_matrix[MATRIX_ROWS];
|
||||
|
||||
// Debouncing: store for each key the number of scans until it's eligible to
|
||||
// change. When scanning the matrix, ignore any changes in keys that have
|
||||
// already changed in the last DEBOUNCE scans.
|
||||
static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS];
|
||||
|
||||
static matrix_row_t read_cols(uint8_t row);
|
||||
static void init_cols(void);
|
||||
static void unselect_rows(void);
|
||||
static void select_row(uint8_t row);
|
||||
|
||||
static uint8_t mcp23018_reset_loop;
|
||||
// static uint16_t mcp23018_reset_loop;
|
||||
|
||||
#ifdef DEBUG_MATRIX_SCAN_RATE
|
||||
uint32_t matrix_timer;
|
||||
uint32_t matrix_scan_count;
|
||||
#endif
|
||||
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_user(void) {}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_user(void) {}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_kb(void) {
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_kb(void) {
|
||||
matrix_scan_user();
|
||||
}
|
||||
|
||||
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
|
||||
mcp23018_status = init_mcp23018();
|
||||
unselect_rows();
|
||||
init_cols();
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
raw_matrix[i] = 0;
|
||||
for (uint8_t j=0; j < MATRIX_COLS; ++j) {
|
||||
debounce_matrix[i * MATRIX_COLS + j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MATRIX_SCAN_RATE
|
||||
matrix_timer = timer_read32();
|
||||
matrix_scan_count = 0;
|
||||
#endif
|
||||
matrix_init_quantum();
|
||||
}
|
||||
|
||||
void matrix_power_up(void) {
|
||||
mcp23018_status = init_mcp23018();
|
||||
|
||||
unselect_rows();
|
||||
init_cols();
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MATRIX_SCAN_RATE
|
||||
matrix_timer = timer_read32();
|
||||
matrix_scan_count = 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Returns a matrix_row_t whose bits are set if the corresponding key should be
|
||||
// eligible to change in this scan.
|
||||
matrix_row_t debounce_mask(matrix_row_t rawcols, uint8_t row) {
|
||||
matrix_row_t result = 0;
|
||||
matrix_row_t change = rawcols ^ raw_matrix[row];
|
||||
raw_matrix[row] = rawcols;
|
||||
for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
|
||||
if (debounce_matrix[row * MATRIX_COLS + i]) {
|
||||
--debounce_matrix[row * MATRIX_COLS + i];
|
||||
} else {
|
||||
result |= (1 << i);
|
||||
}
|
||||
if (change & (1 << i)) {
|
||||
debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
matrix_row_t debounce_read_cols(uint8_t row) {
|
||||
// Read the row without debouncing filtering and store it for later usage.
|
||||
matrix_row_t cols = read_cols(row);
|
||||
// Get the Debounce mask.
|
||||
matrix_row_t mask = debounce_mask(cols, row);
|
||||
// debounce the row and return the result.
|
||||
return (cols & mask) | (matrix[row] & ~mask);;
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
// Then the keyboard
|
||||
if (mcp23018_status) { // if there was an error
|
||||
if (++mcp23018_reset_loop == 0) {
|
||||
// if (++mcp23018_reset_loop >= 1300) {
|
||||
// since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
|
||||
// this will be approx bit more frequent than once per second
|
||||
print("trying to reset mcp23018\n");
|
||||
mcp23018_status = init_mcp23018();
|
||||
if (mcp23018_status) {
|
||||
print("left side not responding\n");
|
||||
} else {
|
||||
print("left side attached\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MATRIX_SCAN_RATE
|
||||
matrix_scan_count++;
|
||||
uint32_t timer_now = timer_read32();
|
||||
if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) {
|
||||
print("matrix scan frequency: ");
|
||||
pdec(matrix_scan_count);
|
||||
print("\n");
|
||||
|
||||
matrix_timer = timer_now;
|
||||
matrix_scan_count = 0;
|
||||
}
|
||||
#endif
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) {
|
||||
select_row(i);
|
||||
// and select on left hand
|
||||
select_row(i + MATRIX_ROWS_PER_SIDE);
|
||||
// we don't need a 30us delay anymore, because selecting a
|
||||
// left-hand row requires more than 30us for i2c.
|
||||
|
||||
// grab cols from left hand
|
||||
matrix[i] = debounce_read_cols(i);
|
||||
// grab cols from right hand
|
||||
matrix[i + MATRIX_ROWS_PER_SIDE] = debounce_read_cols(i + MATRIX_ROWS_PER_SIDE);
|
||||
|
||||
unselect_rows();
|
||||
}
|
||||
|
||||
matrix_scan_quantum();
|
||||
|
||||
#ifdef DEBUG_MATRIX
|
||||
for (uint8_t c = 0; c < MATRIX_COLS; c++)
|
||||
for (uint8_t r = 0; r < MATRIX_ROWS; r++)
|
||||
if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool matrix_is_modified(void) // deprecated and evidently not called.
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Remember this means ROWS
|
||||
static void init_cols(void)
|
||||
{
|
||||
// init on mcp23018
|
||||
// not needed, already done as part of init_mcp23018()
|
||||
|
||||
// Input with pull-up(DDR:0, PORT:1)
|
||||
DDRF &= ~FMASK;
|
||||
PORTF |= FMASK;
|
||||
}
|
||||
|
||||
static matrix_row_t read_cols(uint8_t row)
|
||||
{
|
||||
if (row < 6) {
|
||||
if (mcp23018_status) { // if there was an error
|
||||
return 0;
|
||||
} else {
|
||||
uint8_t data = 0;
|
||||
mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out;
|
||||
data = (~((uint8_t)mcp23018_status) >> 2) & 0x01 ;
|
||||
mcp23018_status = I2C_STATUS_SUCCESS;
|
||||
out:
|
||||
i2c_stop();
|
||||
|
||||
#ifdef DEBUG_MATRIX
|
||||
if (data != 0x00) xprintf("I2C: %d\n", data);
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
} else {
|
||||
// Read using bitmask
|
||||
return ~((((PINF & ROW1) >> 5)) & 0x1);
|
||||
}
|
||||
}
|
||||
|
||||
// Row pin configuration
|
||||
static void unselect_rows(void)
|
||||
{
|
||||
// no need to unselect on mcp23018, because the select step sets all
|
||||
// the other row bits high, and it's not changing to a different
|
||||
// direction
|
||||
// Hi-Z(DDR:0, PORT:0) to unselect
|
||||
DDRB &= ~BMASK;
|
||||
PORTB &= ~BMASK;
|
||||
DDRD &= ~DMASK;
|
||||
PORTD &= ~DMASK;
|
||||
}
|
||||
|
||||
static void select_row(uint8_t row)
|
||||
{
|
||||
if (row < 6) {
|
||||
// select on mcp23018
|
||||
if (mcp23018_status) { // do nothing on error
|
||||
// Read using bitmask
|
||||
} else { // set active row low : 0 // set other rows hi-Z : 1
|
||||
mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
mcp23018_status = i2c_write(~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
|
||||
out:
|
||||
i2c_stop();
|
||||
}
|
||||
} else {
|
||||
// Output low(DDR:1, PORT:0) to select
|
||||
switch (row) {
|
||||
case 6:
|
||||
DDRB |= COL6;
|
||||
PORTB &= ~COL6;
|
||||
break;
|
||||
case 7:
|
||||
DDRB |= COL7;
|
||||
PORTB &= ~COL7;
|
||||
break;
|
||||
case 8:
|
||||
DDRB |= COL8;
|
||||
PORTB &= ~COL8;
|
||||
break;
|
||||
case 9:
|
||||
DDRB |= COL9;
|
||||
PORTB &= ~COL9;
|
||||
break;
|
||||
case 10:
|
||||
DDRD |= COL10;
|
||||
PORTD &= ~COL10;
|
||||
break;
|
||||
case 11:
|
||||
DDRD |= COL11;
|
||||
PORTD &= ~COL11;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
# Gergo
|
||||
|
||||
![ErgoTaco](https://i.redd.it/dbcu5i21m3i21.jpg)
|
||||
|
||||
It's a Taco with a side of HASL. A 12 key fiesta of a board.
|
||||
|
||||
Keyboard Maintainer: [Jeremy Bernhardt](https://github.com/germ)
|
||||
Hardware Supported: ErgoTaco
|
||||
Hardware Availability: [gboards.ca](http://gboards.ca)
|
||||
|
||||
## Firmware building
|
||||
Clone the QMK Repo and install dfu-programmer, flash with:
|
||||
|
||||
make ergotaco:default:dfu
|
||||
|
||||
And reset your keyboard!
|
||||
|
||||
To just test if your build system is sane, try compiling the default keymap using:
|
||||
|
||||
make ergotaco:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
||||
|
||||
## Have an idea? [Reach out to me!](mailto:bernhardtjeremy@gmail.com)
|
@ -0,0 +1,26 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# make ergotaco:default:dfu
|
||||
# Make sure you have dfu-programmer installed!
|
||||
# Do not edit this file! Make a copy of keymaps/default and modify that!
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Hardware info
|
||||
MCU = atmega32u4
|
||||
F_CPU = 16000000
|
||||
ARCH = AVR8
|
||||
BOOTLOADER = atmel-dfu
|
||||
F_USB = $(F_CPU)
|
||||
|
||||
CUSTOM_MATRIX = yes
|
||||
EXTRAKEY_ENABLE = yes
|
||||
CONSOLE_ENABLE = yes
|
||||
COMMAND_ENABLE = yes
|
||||
|
||||
# A bunch of stuff that you shouldn't touch unless you
|
||||
# know what you're doing.
|
||||
#
|
||||
# No touchy, capiche?
|
||||
SRC += matrix.c i2c_master.c
|
||||
ifeq ($(strip $(DEBUG_MATRIX)), yes)
|
||||
OPT_DEFS += -DDEBUG_MATRIX
|
||||
endif
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
Copyright 2019 Vladislav Opara <Deckweiss75@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x0690
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER MMO_Corp
|
||||
#define PRODUCT hacked_motospeed
|
||||
#define DESCRIPTION Motospeed Numpads wired to Teensy++2.0
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 10
|
||||
#define MATRIX_COLS 12
|
||||
|
||||
/*
|
||||
* Keyboard Matrix Assignments
|
||||
*
|
||||
* Change this to how you wired your keyboard
|
||||
* COLS: AVR pins used for columns, left to right
|
||||
* ROWS: AVR pins used for rows, top to bottom
|
||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||
*
|
||||
*/
|
||||
|
||||
// WR XR YR ZR VR ZL YL XL WL VL
|
||||
#define MATRIX_ROW_PINS { B3, B5, F1, B4, B6, D5, D4, D6, D7, C4}
|
||||
|
||||
// ER DR CR BR AR FR FL AL BL CL DL EL
|
||||
#define MATRIX_COL_PINS { F7, F6, F5, F4, F3, F2, E0, E1, C0, C1, C2, C3 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW, ROW2COL*/
|
||||
//#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/*
|
||||
* Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
|
||||
*/
|
||||
//#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
// #define BACKLIGHT_BREATHING
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
|
||||
// #define RGB_DI_PIN E2
|
||||
// #ifdef RGB_DI_PIN
|
||||
// #define RGBLED_NUM 16
|
||||
// #define RGBLIGHT_HUE_STEP 8
|
||||
// #define RGBLIGHT_SAT_STEP 8
|
||||
// #define RGBLIGHT_VAL_STEP 8
|
||||
// #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
|
||||
// #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
|
||||
// /*== all animations enable ==*/
|
||||
// #define RGBLIGHT_ANIMATIONS
|
||||
// /*== or choose animations ==*/
|
||||
// #define RGBLIGHT_EFFECT_BREATHING
|
||||
// #define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
// #define RGBLIGHT_EFFECT_SNAKE
|
||||
// #define RGBLIGHT_EFFECT_KNIGHT
|
||||
// #define RGBLIGHT_EFFECT_CHRISTMAS
|
||||
// #define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
// #define RGBLIGHT_EFFECT_RGB_TEST
|
||||
// #define RGBLIGHT_EFFECT_ALTERNATING
|
||||
// #endif
|
||||
|
||||
/* 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
|
||||
|
||||
/* number of backlight levels */
|
||||
|
||||
/* 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
|
||||
|
||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
|
||||
* This is userful for the Windows task manager shortcut (ctrl+shift+esc).
|
||||
*/
|
||||
// #define GRAVE_ESC_CTRL_OVERRIDE
|
||||
|
||||
/*
|
||||
* Force NKRO
|
||||
*
|
||||
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
|
||||
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
|
||||
* makefile for this to work.)
|
||||
*
|
||||
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
|
||||
* until the next keyboard reset.
|
||||
*
|
||||
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
|
||||
* fully operational during normal computer usage.
|
||||
*
|
||||
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
|
||||
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
|
||||
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
|
||||
* power-up.
|
||||
*
|
||||
*/
|
||||
#define FORCE_NKRO
|
||||
|
||||
/*
|
||||
* Magic Key Options
|
||||
*
|
||||
* Magic keys are hotkey commands that allow control over firmware functions of
|
||||
* the keyboard. They are best used in combination with the HID Listen program,
|
||||
* found here: https://www.pjrc.com/teensy/hid_listen.html
|
||||
*
|
||||
* The options below allow the magic key functionality to be changed. This is
|
||||
* useful if your keyboard/keypad is missing keys and you want magic key support.
|
||||
*
|
||||
*/
|
||||
|
||||
/* key combination for magic key command */
|
||||
/* defined by default; to change, uncomment and set to the combination you want */
|
||||
// #define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
|
||||
|
||||
/* control how magic key switches layers */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
|
||||
|
||||
/* override magic key keymap */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
//#define MAGIC_KEY_HELP H
|
||||
//#define MAGIC_KEY_HELP_ALT SLASH
|
||||
//#define MAGIC_KEY_DEBUG D
|
||||
//#define MAGIC_KEY_DEBUG_MATRIX X
|
||||
//#define MAGIC_KEY_DEBUG_KBD K
|
||||
//#define MAGIC_KEY_DEBUG_MOUSE M
|
||||
//#define MAGIC_KEY_VERSION V
|
||||
//#define MAGIC_KEY_STATUS S
|
||||
//#define MAGIC_KEY_CONSOLE C
|
||||
//#define MAGIC_KEY_LAYER0 0
|
||||
//#define MAGIC_KEY_LAYER0_ALT GRAVE
|
||||
//#define MAGIC_KEY_LAYER1 1
|
||||
//#define MAGIC_KEY_LAYER2 2
|
||||
//#define MAGIC_KEY_LAYER3 3
|
||||
//#define MAGIC_KEY_LAYER4 4
|
||||
//#define MAGIC_KEY_LAYER5 5
|
||||
//#define MAGIC_KEY_LAYER6 6
|
||||
//#define MAGIC_KEY_LAYER7 7
|
||||
//#define MAGIC_KEY_LAYER8 8
|
||||
//#define MAGIC_KEY_LAYER9 9
|
||||
//#define MAGIC_KEY_BOOTLOADER B
|
||||
//#define MAGIC_KEY_BOOTLOADER_ALT ESC
|
||||
//#define MAGIC_KEY_LOCK CAPS
|
||||
//#define MAGIC_KEY_EEPROM E
|
||||
//#define MAGIC_KEY_EEPROM_CLEAR BSPACE
|
||||
//#define MAGIC_KEY_NKRO N
|
||||
//#define MAGIC_KEY_SLEEP_LED Z
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
//#define MIDI_BASIC
|
||||
|
||||
/* enable advanced MIDI features:
|
||||
- MIDI notes can be added to the keymap
|
||||
- Octave shift and transpose
|
||||
- Virtual sustain, portamento, and modulation wheel
|
||||
- etc.
|
||||
*/
|
||||
//#define MIDI_ADVANCED
|
||||
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 1
|
||||
|
||||
/*
|
||||
* HD44780 LCD Display Configuration
|
||||
*/
|
||||
/*
|
||||
#define LCD_LINES 2 //< number of visible lines of the display
|
||||
#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display
|
||||
|
||||
#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode
|
||||
|
||||
#if LCD_IO_MODE
|
||||
#define LCD_PORT PORTB //< port for the LCD lines
|
||||
#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0
|
||||
#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1
|
||||
#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2
|
||||
#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3
|
||||
#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0
|
||||
#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1
|
||||
#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2
|
||||
#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3
|
||||
#define LCD_RS_PORT LCD_PORT //< port for RS line
|
||||
#define LCD_RS_PIN 3 //< pin for RS line
|
||||
#define LCD_RW_PORT LCD_PORT //< port for RW line
|
||||
#define LCD_RW_PIN 2 //< pin for RW line
|
||||
#define LCD_E_PORT LCD_PORT //< port for Enable line
|
||||
#define LCD_E_PIN 1 //< pin for Enable line
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Bootmagic Lite key configuration */
|
||||
// #define BOOTMAGIC_LITE_ROW 0
|
||||
// #define BOOTMAGIC_LITE_COLUMN 0
|
@ -0,0 +1,43 @@
|
||||
/* Copyright 2019 Vladislav Opara <Deckweiss75@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "hacked_motospeed.h"
|
||||
|
||||
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
|
||||
|
||||
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,46 @@
|
||||
/* Copyright 2019 Vladislav Opara <Deckweiss75@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
/* This a shortcut to help you visually see your layout.
|
||||
*
|
||||
* The first section contains all of the arguments representing the physical
|
||||
* layout of the board and position of the keys.
|
||||
*
|
||||
* The second converts the arguments into a two-dimensional array which
|
||||
* represents the switch matrix.
|
||||
*/
|
||||
#define LAYOUT( \
|
||||
EWR, DWR, CWR, BWR, AWR, FXR, FYL, AZL, BZL, CZL, DZL, \
|
||||
DXR, CXR, BXR, AXR, FZR, DVL, AYL, BYL, CYL, DYL, EZL, \
|
||||
EZR, DYR, CYR, BYR, AYR, DVR, FZL, AXL, BXL, CXL, DXL, \
|
||||
DZR, CZR, BZR, AZR, FYR, FXL, AWL, BWL, CWL, DWL, EWL \
|
||||
) \
|
||||
{ \
|
||||
{ EWR, DWR, CWR, BWR, AWR, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_NO, DXR, CXR, BXR, AXR, FXR, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_NO, DYR, CYR, BYR, AYR, FYR, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
|
||||
{ EZR, DZR, CZR, AZR, BZR, FZR, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_NO, DVR, 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, FZL, BZL, AZL, CZL, DZL, EZL }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, FYL, AYL, BYL, CYL, DYL, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, FXL, AXL, BXL, CXL, DXL, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, AWL, BWL, CWL, DWL, EWL }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, DVL, KC_NO } \
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"keyboard_name": "Hacked Motospeed",
|
||||
"url": "",
|
||||
"maintainer": "Deckweiss",
|
||||
"width": 13,
|
||||
"height": 4,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [{"label":"ESC", "x":0, "y":0, "h":2}, {"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":"Z", "x":7, "y":0}, {"label":"U", "x":8, "y":0}, {"label":"I", "x":9, "y":0}, {"label":"O", "x":10, "y":0}, {"label":"P", "x":11, "y":0, "w":2}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":7, "y":1}, {"label":"J", "x":8, "y":1}, {"label":"K", "x":9, "y":1}, {"label":"L", "x":10, "y":1}, {"label":"(", "x":11, "y":1}, {"label":")", "x":12, "y":1}, {"label":"=", "x":0, "y":2}, {"label":"Y", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":7, "y":2}, {"label":"M", "x":8, "y":2}, {"label":",", "x":9, "y":2}, {"label":".", "x":10, "y":2}, {"label":"?", "x":11, "y":2}, {"label":"Fn", "x":0, "y":3, "w":2}, {"label":"Num", "x":2, "y":3}, {"label":"Bksp", "x":3, "y":3}, {"label":"Enter", "x":4, "y":3}, {"label":"Spc", "x":5, "y":3}, {"label":"LShift", "x":7, "y":3}, {"label":"LCtrl", "x":8, "y":3}, {"label":"LAlt", "x":9, "y":3}, {"label":"RAlt", "x":10, "y":3}, {"label":"Meta", "x":11, "y":3}, {"label":"Fn", "x":12, "y":2, "h":2}]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/* Copyright 2019 Vladislav Opara <Deckweiss75@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
@ -0,0 +1,65 @@
|
||||
/* Copyright 2019 Vladislav Opara <Deckweiss75@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
// Defines the keycodes used by our macros in process_record_user
|
||||
enum custom_keycodes {
|
||||
QMKBEST = SAFE_RANGE,
|
||||
QMKURL
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT( /* Base */
|
||||
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, \
|
||||
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_LPRN, KC_RPRN, \
|
||||
KC_PEQL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, KC_QUES, \
|
||||
XXXXXXX, XXXXXXX, KC_BSPC, KC_ENT, KC_SPC, KC_LSFT, KC_LCTRL, KC_LALT, KC_ALGR, KC_LWIN, XXXXXXX \
|
||||
),
|
||||
};
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case QMKBEST:
|
||||
if (record->event.pressed) {
|
||||
// when keycode QMKBEST is pressed
|
||||
SEND_STRING("QMK is the best thing ever!");
|
||||
} else {
|
||||
// when keycode QMKBEST is released
|
||||
}
|
||||
break;
|
||||
case QMKURL:
|
||||
if (record->event.pressed) {
|
||||
// when keycode QMKURL is pressed
|
||||
SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER));
|
||||
} else {
|
||||
// when keycode QMKURL is released
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void matrix_init_user(void) {
|
||||
|
||||
}
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
|
||||
}
|
||||
|
||||
void led_set_user(uint8_t usb_led) {
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
# The default keymap for hacked_motospeed
|
@ -0,0 +1,23 @@
|
||||
# hacked_motospeed
|
||||
|
||||
This is a
|
||||
- tiny (44key),
|
||||
- budget (~50€ total expense),
|
||||
- portable (HID bluetooth & 5aH battery)
|
||||
- easy to diy (little wiring & soldering needed),
|
||||
|
||||
mechanical keyboard.
|
||||
It is made by wiring two Motospeed K22 numpads to a Teensy++ 2.0, while reusing as much of the original PCB as possible.
|
||||
The numpads come with Outemu red linear switches.
|
||||
(A detailed guide will be posted and linked later)
|
||||
|
||||
|
||||
Keyboard Maintainer: [Deckweiss](https://github.com/Deckweiss)
|
||||
Hardware Supported: Motospeed K22 numpads wired to Teensy++ 2.0 according to my guide (upcoming).
|
||||
Hardware Availability: Ebay, AliExpress
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make handwired/hacked_motospeed:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
@ -0,0 +1,81 @@
|
||||
# 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 selection
|
||||
# Teensy halfkay
|
||||
# Pro Micro caterina
|
||||
# Atmel DFU atmel-dfu
|
||||
# LUFA DFU lufa-dfu
|
||||
# QMK DFU qmk-dfu
|
||||
# atmega32a bootloadHID
|
||||
BOOTLOADER = halfkay
|
||||
|
||||
|
||||
# If you don't know the bootloader type, then you can specify the
|
||||
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
# OPT_DEFS += -DBOOTLOADER_SIZE=1024
|
||||
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = yes # Console for debug(+400)
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
# 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 = yes # Enable keyboard backlight functionality on B7 by default
|
||||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||
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
|
||||
HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400)
|
@ -0,0 +1,240 @@
|
||||
/*
|
||||
Copyright 2018 Jack Hildebrandt
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0x1EEE
|
||||
#define PRODUCT_ID 0x1313
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER Jsck
|
||||
#define PRODUCT Tennie
|
||||
#define DESCRIPTION Ten key macropad
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 3
|
||||
#define MATRIX_COLS 4
|
||||
|
||||
/*
|
||||
* Keyboard Matrix Assignments
|
||||
*
|
||||
* Change this to how you wired your keyboard
|
||||
* COLS: AVR pins used for columns, left to right
|
||||
* ROWS: AVR pins used for rows, top to bottom
|
||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||
*
|
||||
*/
|
||||
#define MATRIX_ROW_PINS { C6, D4, D0}
|
||||
#define MATRIX_COL_PINS { D7, E6, B4, B5 }
|
||||
#define UNUSED_PINS { B1, B2, B3, B6, F4, F5, F6, F7 D1}
|
||||
|
||||
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/*
|
||||
* Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
|
||||
*/
|
||||
//#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
|
||||
|
||||
// #define BACKLIGHT_PIN B7
|
||||
// #define BACKLIGHT_BREATHING
|
||||
// #define BACKLIGHT_LEVELS 3
|
||||
#define RGBW
|
||||
#define RGB_DI_PIN D1
|
||||
#ifdef RGB_DI_PIN
|
||||
#define RGBLED_NUM 1
|
||||
#define RGBLIGHT_HUE_STEP 8
|
||||
#define RGBLIGHT_SAT_STEP 8
|
||||
#define RGBLIGHT_VAL_STEP 8
|
||||
#define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
|
||||
// #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
|
||||
// /*== all animations enable ==*/
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
// /*== or choose animations ==*/
|
||||
// #define RGBLIGHT_EFFECT_BREATHING
|
||||
// #define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
// #define RGBLIGHT_EFFECT_SNAKE
|
||||
// #define RGBLIGHT_EFFECT_KNIGHT
|
||||
// #define RGBLIGHT_EFFECT_CHRISTMAS
|
||||
// #define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
// #define RGBLIGHT_EFFECT_RGB_TEST
|
||||
// #define RGBLIGHT_EFFECT_ALTERNATING
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
/* number of backlight levels */
|
||||
|
||||
/* 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
|
||||
|
||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
|
||||
* This is userful for the Windows task manager shortcut (ctrl+shift+esc).
|
||||
*/
|
||||
// #define GRAVE_ESC_CTRL_OVERRIDE
|
||||
|
||||
/*
|
||||
* Force NKRO
|
||||
*
|
||||
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
|
||||
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
|
||||
* makefile for this to work.)
|
||||
*
|
||||
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
|
||||
* until the next keyboard reset.
|
||||
*
|
||||
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
|
||||
* fully operational during normal computer usage.
|
||||
*
|
||||
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
|
||||
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
|
||||
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
|
||||
* power-up.
|
||||
*
|
||||
*/
|
||||
//#define FORCE_NKRO
|
||||
|
||||
/*
|
||||
* Magic Key Options
|
||||
*
|
||||
* Magic keys are hotkey commands that allow control over firmware functions of
|
||||
* the keyboard. They are best used in combination with the HID Listen program,
|
||||
* found here: https://www.pjrc.com/teensy/hid_listen.html
|
||||
*
|
||||
* The options below allow the magic key functionality to be changed. This is
|
||||
* useful if your keyboard/keypad is missing keys and you want magic key support.
|
||||
*
|
||||
*/
|
||||
|
||||
/* control how magic key switches layers */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
|
||||
|
||||
/* override magic key keymap */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
//#define MAGIC_KEY_HELP1 H
|
||||
//#define MAGIC_KEY_HELP2 SLASH
|
||||
//#define MAGIC_KEY_DEBUG D
|
||||
//#define MAGIC_KEY_DEBUG_MATRIX X
|
||||
//#define MAGIC_KEY_DEBUG_KBD K
|
||||
//#define MAGIC_KEY_DEBUG_MOUSE M
|
||||
//#define MAGIC_KEY_VERSION V
|
||||
//#define MAGIC_KEY_STATUS S
|
||||
//#define MAGIC_KEY_CONSOLE C
|
||||
//#define MAGIC_KEY_LAYER0_ALT1 ESC
|
||||
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
|
||||
//#define MAGIC_KEY_LAYER0 0
|
||||
//#define MAGIC_KEY_LAYER1 1
|
||||
//#define MAGIC_KEY_LAYER2 2
|
||||
//#define MAGIC_KEY_LAYER3 3
|
||||
//#define MAGIC_KEY_LAYER4 4
|
||||
//#define MAGIC_KEY_LAYER5 5
|
||||
//#define MAGIC_KEY_LAYER6 6
|
||||
//#define MAGIC_KEY_LAYER7 7
|
||||
//#define MAGIC_KEY_LAYER8 8
|
||||
//#define MAGIC_KEY_LAYER9 9
|
||||
//#define MAGIC_KEY_BOOTLOADER PAUSE
|
||||
//#define MAGIC_KEY_LOCK CAPS
|
||||
//#define MAGIC_KEY_EEPROM E
|
||||
//#define MAGIC_KEY_NKRO N
|
||||
//#define MAGIC_KEY_SLEEP_LED Z
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
//#define MIDI_BASIC
|
||||
|
||||
/* enable advanced MIDI features:
|
||||
- MIDI notes can be added to the keymap
|
||||
- Octave shift and transpose
|
||||
- Virtual sustain, portamento, and modulation wheel
|
||||
- etc.
|
||||
*/
|
||||
//#define MIDI_ADVANCED
|
||||
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 1
|
||||
|
||||
/*
|
||||
* HD44780 LCD Display Configuration
|
||||
*/
|
||||
/*
|
||||
#define LCD_LINES 2 //< number of visible lines of the display
|
||||
#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display
|
||||
|
||||
#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode
|
||||
|
||||
#if LCD_IO_MODE
|
||||
#define LCD_PORT PORTB //< port for the LCD lines
|
||||
#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0
|
||||
#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1
|
||||
#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2
|
||||
#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3
|
||||
#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0
|
||||
#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1
|
||||
#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2
|
||||
#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3
|
||||
#define LCD_RS_PORT LCD_PORT //< port for RS line
|
||||
#define LCD_RS_PIN 3 //< pin for RS line
|
||||
#define LCD_RW_PORT LCD_PORT //< port for RW line
|
||||
#define LCD_RW_PIN 2 //< pin for RW line
|
||||
#define LCD_E_PORT LCD_PORT //< port for Enable line
|
||||
#define LCD_E_PIN 1 //< pin for Enable line
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Bootmagic Lite key configuration */
|
||||
//#define BOOTMAGIC_LITE_ROW 0
|
||||
//#define BOOTMAGIC_LITE_COLUMN 0
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"keyboard_name": "Tennie",
|
||||
"url": "https://github.com/StoutIEEE/macropad-workshop",
|
||||
"maintainer": "UW Stout IEEE, Jack Hildebrandt (onemorebyte)",
|
||||
"width": 4,
|
||||
"height": 3,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [{"x":0.5, "y":0}, {"x":1.5, "y":0}, {"x":2.5, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":0.5, "y":2}, {"x":1.5, "y":2}, {"x":2.5, "y":2}]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/* Copyright 2018 REPLACE_WITH_YOUR_NAME
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
@ -0,0 +1,95 @@
|
||||
/* Copyright 2018 Jack H.
|
||||
*
|
||||
* 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
|
||||
|
||||
#define TAPPING_TOGGLE 2
|
||||
|
||||
|
||||
// Layer names
|
||||
#define base 0
|
||||
#define shrek 1
|
||||
#define ogre 2
|
||||
#define tcp 3
|
||||
|
||||
// Layer Switches
|
||||
#define KC_SHRK TT(shrek)
|
||||
#define KC_OGRE TT(ogre)
|
||||
#define KC_TCP TT(tcp)
|
||||
|
||||
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[base] = LAYOUT(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
KC_DEL, KC_SPC, KC_ENT,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_LEFT, KC_DOWN, KC_UP , KC_RGHT,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_SHRK, KC_OGRE, KC_TCP
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
[shrek] = LAYOUT(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
KC_MPRV, KC_MPLY, KC_MNXT,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_BRID, KC_VOLD, KC_VOLU, KC_BRIU,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
_______, _______, _______
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
[ogre] = LAYOUT(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
RGB_MOD, RGB_TOG, RGB_RMOD,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_F13, KC_F14, KC_F15, KC_F16,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
_______, _______, _______
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
[tcp] = LAYOUT(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
KC_WBAK, KC_WREF, KC_WFWD,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
XXXXXXX, KC_PGDN, KC_PGUP, XXXXXXX,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
_______, _______, _______
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
};
|
@ -0,0 +1,68 @@
|
||||
# Default keymap
|
||||
|
||||
This keymap is to serve as an example of how you could make a multi-layer keymap.
|
||||
|
||||
#### keymap
|
||||
|
||||
```
|
||||
[base] = LAYOUT_kc(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
DEL , SPC , ENT ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
LEFT , DOWN , UP , RGHT ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
SHRK , OGRE , TCP
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
[shrek] = LAYOUT_kc(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
MPRV , MPLY , MNXT ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
BRID , VOLD , VOLU , BRIU ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
_______, _______, _______
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
[ogre] = LAYOUT_kc(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
RGB_MOD, RGB_TOG, RGB_RMOD
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
F13 , F14 , F15 , F16 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
_______, _______, _______
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
[tcp] = LAYOUT_kc(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
WBAK , WREF , WFWD ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
XXXXXXX , PGDN , PGUP , XXXXXXX ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
_______, _______, _______
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
```
|
@ -0,0 +1,19 @@
|
||||
/* Copyright 2018 Jack Hildebrandt
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
@ -0,0 +1,37 @@
|
||||
/* Copyright 2018 Jack Hildebrandt
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
// Layer names
|
||||
#define base 0
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[base] = LAYOUT(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
KC_1 , KC_2 , KC_3 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_4 , KC_5 , KC_6 , KC_7 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_8 , KC_9 , KC_0
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
# Simple numberpad keymap
|
||||
|
||||
This keymap is to test the soldering work of workshop participants. It can also be used as a simple base for a macropad keymap.
|
||||
```
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
1 , 2 , 3 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
4 , 5 , 6 , 7 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
8 , 9 , 0
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
```
|
@ -0,0 +1,19 @@
|
||||
/* Copyright 2018 Jacob Hillebrand
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
@ -0,0 +1,37 @@
|
||||
/* Copyright 2018 Jacob Hillebrand
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
// Layer names
|
||||
#define base 0
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[base] = LAYOUT(
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
KC_F13 , KC_F14 , KC_F15 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_F16 , KC_F17 , KC_F18 , KC_F19 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
KC_F20, KC_F21 , KC_F22
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
),
|
||||
};
|
@ -0,0 +1,19 @@
|
||||
# Soundboard keymap
|
||||
|
||||
This keymap binds all keys to function keys 13-22 for something like a
|
||||
soundboard (ie:[Resanance](https://www.reddit.com/r/discordapp/comments/44ldc1/soundboard_for_discord/))
|
||||
```
|
||||
// ┌────────┬────────┬────────┐
|
||||
|
||||
F13 , F14 , F15 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
F16 , F17 , F18 , F19 ,
|
||||
|
||||
// ├────────┼────────┼────────┼────────┼
|
||||
|
||||
F20 , F21 , F22
|
||||
|
||||
// └────────┴────────┴────────┘
|
||||
```
|
@ -0,0 +1,15 @@
|
||||
# Tennie
|
||||
|
||||
![tennie](https://raw.githubusercontent.com/StoutIEEE/macropad-workshop/master/images/macropad.jpg)
|
||||
|
||||
A ten key macropad for a club workshop! More information, and build instructions can be found [here](https://github.com/StoutIEEE/macropad-workshop)
|
||||
|
||||
Keyboard Maintainer: [Jack Hildebrandt](https://github.com/onemorebyte), [UW Stout IEEE](https://github.com/StoutIEEE)
|
||||
|
||||
Hardware Supported: ProMicro
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make handwired/tennie:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
@ -0,0 +1,80 @@
|
||||
# MCU name
|
||||
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 selection
|
||||
# Teensy halfkay
|
||||
# Pro Micro caterina
|
||||
# Atmel DFU atmel-dfu
|
||||
# LUFA DFU lufa-dfu
|
||||
# QMK DFU qmk-dfu
|
||||
# atmega32a bootloadHID
|
||||
BOOTLOADER = caterina
|
||||
|
||||
|
||||
# If you don't know the bootloader type, then you can specify the
|
||||
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
# OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = lite # 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 = no # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
|
||||
RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
|
||||
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
|
||||
HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400)
|
@ -0,0 +1,45 @@
|
||||
/* Copyright 2018 Jack Hildebrandt
|
||||
*
|
||||
* 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 "tennie.h"
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
void matrix_post_init(void) {
|
||||
rgblight_enable_noeeprom();
|
||||
keyboard_post_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
|
||||
|
||||
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,37 @@
|
||||
/* Copyright 2018 Jack Hildebrandt
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
/* This a shortcut to help you visually see your layout.
|
||||
*
|
||||
* The first section contains all of the arguments representing the physical
|
||||
* layout of the board and position of the keys.
|
||||
*
|
||||
* The second converts the arguments into a two-dimensional array which
|
||||
* represents the switch matrix.
|
||||
*/
|
||||
#define LAYOUT( \
|
||||
K00, K01, K02, \
|
||||
K10, K11, K12, K13, \
|
||||
K20, K21, K22 \
|
||||
) \
|
||||
{ \
|
||||
{ K00, K01, K02, KC_NO }, \
|
||||
{ K10, K11, K12, K13 }, \
|
||||
{ K20, K21, K22, KC_NO }, \
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2018 Yiancar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/* Include overwrites for specific keymap */
|
||||
|
||||
#define HS60_HHKB
|
||||
#undef PRODUCT_ID
|
||||
#define PRODUCT_ID 0x4855
|
||||
|
||||
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_0
|
||||
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_1
|
||||
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_2
|
||||
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_3
|
||||
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_4
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0000000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0000000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0011000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0011000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0011100000000111
|
||||
|
||||
#undef RGB_BACKLIGHT_CAPS_LOCK_INDICATOR
|
||||
#define RGB_BACKLIGHT_CAPS_LOCK_INDICATOR { .color = { .h = 0, .s = 255 }, .index = 3-1 } //red
|
@ -0,0 +1,71 @@
|
||||
/* Copyright 2018 Yiancar
|
||||
*
|
||||
* 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
|
||||
|
||||
//This is the HHKB version of the PCB
|
||||
|
||||
enum macro_keys {
|
||||
KC_EML = SAFE_RANGE
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT_60_hhkb( /* Base */
|
||||
KC_ESC, 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_BSLS,\
|
||||
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_BSPC,\
|
||||
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(1),\
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL ),
|
||||
|
||||
[1] = LAYOUT_60_hhkb( /* FN */
|
||||
RESET, 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_TRNS, KC_TRNS,\
|
||||
KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, BR_DEC, BR_INC, ES_DEC, ES_INC, KC_UP, KC_TRNS, KC_DEL, \
|
||||
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, \
|
||||
KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,\
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS ),
|
||||
|
||||
[2] = LAYOUT_60_hhkb( /* Empty for dynamic keymaps */
|
||||
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_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 ),
|
||||
|
||||
[3] = LAYOUT_60_hhkb( /* Empty for dynamic keymaps */
|
||||
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_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 ),
|
||||
};
|
||||
|
||||
void matrix_init_user(void) {
|
||||
//user initialization
|
||||
}
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
//user matrix
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case KC_EML: //use "KC_EML" as keycode in layers above to call macro
|
||||
if (!record->event.pressed) {
|
||||
send_string_with_delay_P(PSTR("example@email.com"), 10); //change email value here
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
The default keymap for HHKB HS60 V2. VIA support enabled.
|
||||
=========================================================
|
||||
|
||||
![Layout image](https://imgur.com/usbrQWL.png)
|
||||
|
||||
Default layer is normal HHKB with 7U space. Fn layer is used for RGB functions, Volume control and arrow cluster
|
@ -0,0 +1,66 @@
|
||||
# project specific files
|
||||
SRC = keyboards/zeal60/zeal60.c \
|
||||
keyboards/zeal60/rgb_backlight.c \
|
||||
drivers/issi/is31fl3733.c \
|
||||
quantum/color.c \
|
||||
drivers/arm/i2c_master.c
|
||||
|
||||
## chip/board settings
|
||||
# the next two should match the directories in
|
||||
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
|
||||
MCU_FAMILY = STM32
|
||||
MCU_SERIES = STM32F3xx
|
||||
|
||||
# Linker script to use
|
||||
# it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# or <this_dir>/ld/
|
||||
MCU_LDSCRIPT = STM32F303xC
|
||||
|
||||
# Startup code to use
|
||||
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
|
||||
MCU_STARTUP = stm32f3xx
|
||||
|
||||
# Board: it should exist either in <chibios>/os/hal/boards/
|
||||
# or <this_dir>/boards
|
||||
BOARD = GENERIC_STM32_F303XC
|
||||
|
||||
# Cortex version
|
||||
MCU = cortex-m4
|
||||
|
||||
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
|
||||
ARMV = 7
|
||||
|
||||
USE_FPU = yes
|
||||
|
||||
# Vector table for application
|
||||
# 0x00000000-0x00001000 area is occupied by bootlaoder.*/
|
||||
# The CORTEX_VTOR... is needed only for MCHCK/Infinity KB
|
||||
# OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000
|
||||
OPT_DEFS =
|
||||
|
||||
# Do not put the microcontroller into power saving mode
|
||||
# when we get USB suspend event. We want it to keep updating
|
||||
# backlight effects.
|
||||
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
|
||||
|
||||
# Options to pass to dfu-util when flashing
|
||||
DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||
CONSOLE_ENABLE = no # Console for debug
|
||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||
AUDIO_ENABLE = no # Audio output on port C6
|
||||
NO_USB_STARTUP_CHECK = no # Disable initialization only when usb is plugged in
|
||||
#SERIAL_LINK_ENABLE = yes
|
||||
|
||||
RAW_ENABLE = yes
|
||||
DYNAMIC_KEYMAP_ENABLE = yes
|
||||
CIE1931_CURVE = yes
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
Base Copyright 2017 Luiz Ribeiro <luizribeiro@gmail.com>
|
||||
Modified 2017 Andrew Novak <ndrw.nvk@gmail.com>
|
||||
Modified 2018 Wayne Jones (WarmCatUK) <waynekjones@gmail.com>
|
||||
Modified 2019 AbstractKB
|
||||
|
||||
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 LicensezZZ
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum layers {
|
||||
_DEFLT,
|
||||
_RAISE,
|
||||
_LOWER,
|
||||
_FN
|
||||
};
|
||||
|
||||
enum custom_keycodes {
|
||||
MYRGB_TG = SAFE_RANGE
|
||||
};
|
||||
|
||||
bool rgbinit = true;
|
||||
bool rgbon = true;
|
||||
|
||||
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {1,5,5}; //only using the first one
|
||||
|
||||
void keyboard_post_init_user(void) {
|
||||
rgblight_enable_noeeprom();
|
||||
led_set_user(host_keyboard_leds());
|
||||
}
|
||||
|
||||
uint32_t layer_state_set_user(uint32_t state) {
|
||||
switch (biton32(state)) {
|
||||
case _RAISE:
|
||||
rgblight_sethsv_noeeprom(240,255,255);
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
|
||||
break;
|
||||
case _LOWER:
|
||||
rgblight_sethsv_noeeprom(0,255,255);
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
|
||||
break;
|
||||
case _FN:
|
||||
rgblight_sethsv_noeeprom(0,255,255);
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_SWIRL);
|
||||
break;
|
||||
default: //_DEFLT
|
||||
rgblight_sethsv_noeeprom(0,0,255);
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void led_set_user(uint8_t usb_led) {
|
||||
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_ALTERNATING);
|
||||
} else {
|
||||
layer_state_set_user(layer_state);
|
||||
}
|
||||
}
|
||||
|
||||
void myrgb_toggle(void) {
|
||||
if (rgbon) {
|
||||
rgblight_disable_noeeprom();
|
||||
rgbon = false;
|
||||
} else {
|
||||
rgblight_enable_noeeprom();
|
||||
layer_state_set_user(layer_state);
|
||||
led_set_user(host_keyboard_leds());
|
||||
rgbon = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch(keycode) {
|
||||
case MYRGB_TG:
|
||||
if (record->event.pressed) {
|
||||
myrgb_toggle();
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_DEFLT] = LAYOUT( \
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_ENT, \
|
||||
KC_BSPC, 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, KC_RSFT, \
|
||||
MO(_FN), KC_LCTL, KC_LGUI, KC_LALT, MO(_LOWER),KC_SPC,KC_SPC,MO(_RAISE),KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
|
||||
),
|
||||
|
||||
|
||||
[_RAISE] = LAYOUT( \
|
||||
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, LCTL(LGUI(KC_LEFT)), LGUI(KC_L), LCTL(LGUI(KC_RGHT)), _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_CAPS, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, KC_MPLY \
|
||||
),
|
||||
|
||||
|
||||
[_LOWER] = LAYOUT( \
|
||||
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_GRV, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, KC_BSLS, _______, \
|
||||
_______, _______, _______, KC_LBRC, KC_RBRC, S(KC_9),S(KC_0),S(KC_LBRC),S(KC_RBRC),_______,_______,_______, \
|
||||
_______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
|
||||
|
||||
[_FN] = LAYOUT( \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, MYRGB_TG \
|
||||
)
|
||||
};
|
@ -0,0 +1,6 @@
|
||||
# My personal layout for the JJ50
|
||||
|
||||
It is an approximation of a 60% layout with the alternate layers set up for programming,
|
||||
with brackets and parenthesis on the homerow
|
||||
Other things I changed were swapping around delete, backspace, and capslock around
|
||||
It also uses layer based rgb underglow, and the underglow flashes when capslock is enabled
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
Copyright 2015 Jack Humbert
|
||||
(Modified) Copyright 2019 AbstractKB
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//my block------------
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#define RGBLIGHT_SLEEP
|
||||
|
||||
/* Use I2C or Serial, not both */
|
||||
|
||||
#define USE_SERIAL
|
||||
// #define USE_I2C
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
#define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
@ -0,0 +1,92 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum layers {
|
||||
_BASE,
|
||||
_LIST
|
||||
};
|
||||
|
||||
enum my_keycodes {
|
||||
MYRGB_TG = SAFE_RANGE
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_BASE] = LAYOUT( \
|
||||
KC_MPLY, KC_PSLS, KC_PAST, 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, MYRGB_TG, KC_PGUP, \
|
||||
KC_MUTE, KC_PPLS, KC_PMNS, 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_DEL, KC_PGDN, \
|
||||
KC_P7, KC_P8, KC_P9, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, \
|
||||
KC_P4, KC_P5, KC_P6, KC_BSPACE, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_CAPS, KC_PSCR, \
|
||||
KC_P1, KC_P2, KC_P3, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, XXXXXXX, KC_INS, \
|
||||
KC_P0, KC_PDOT, KC_PENT, TO(_LIST), KC_LCTL, KC_LGUI, KC_LALT, XXXXXXX, KC_SPC, KC_SPC, XXXXXXX, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX \
|
||||
),
|
||||
|
||||
[_LIST] = LAYOUT( \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, TO(_BASE), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
|
||||
)
|
||||
|
||||
};
|
||||
|
||||
bool rgbinit = true;
|
||||
bool rgbon = true;
|
||||
|
||||
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {1,5,5}; //only using the first one
|
||||
|
||||
void matrix_post_init_user(void) {
|
||||
rgblight_enable_noeeprom();
|
||||
led_set_user(host_keyboard_leds());
|
||||
}
|
||||
|
||||
uint32_t layer_state_set_user(uint32_t state) {
|
||||
switch (biton32(state)) {
|
||||
case _LIST:
|
||||
rgblight_sethsv_noeeprom(0,255,255);
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_SWIRL);
|
||||
break;
|
||||
default: //_BASE
|
||||
rgblight_sethsv_noeeprom(0,0,255);
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void led_set_user(uint8_t usb_led) {
|
||||
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
|
||||
rgblight_mode_noeeprom(RGBLIGHT_MODE_ALTERNATING);
|
||||
} else {
|
||||
layer_state_set_user(layer_state);
|
||||
}
|
||||
}
|
||||
|
||||
void myrgb_toggle(void) {
|
||||
if (rgbon) {
|
||||
rgblight_disable_noeeprom();
|
||||
rgbon = false;
|
||||
} else {
|
||||
rgblight_enable_noeeprom();
|
||||
layer_state_set_user(layer_state);
|
||||
led_set_user(host_keyboard_leds());
|
||||
rgbon = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch(keycode) {
|
||||
case MYRGB_TG:
|
||||
if (record->event.pressed) {
|
||||
myrgb_toggle();
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
# My personal layout for the BFO-9000
|
||||
|
||||
It is an approximation of a 96% layout with a left-hand number pad
|
||||
Other things I changed were swapping around delete, backspace, and capslock
|
||||
It also uses layer based rgb underglow, and the underglow flashes when capslock is enabled
|
@ -0,0 +1 @@
|
||||
RGBLIGHT_ENABLE = yes
|
@ -1,3 +1,5 @@
|
||||
# Colemak layout for Iris rev2.1 with Mac and Windows layers and a Gaming Layer.
|
||||
# Symbol layer is based on my Planck layout, so it provides numbers, symbols, and volume controls.
|
||||
# Two Navigation layers, for Mac and Windows Colemak layers respectively.
|
||||
# Iris
|
||||
|
||||
This is a simple Colemak layout for Iris rev2.1 with Mac and Windows layers and a Gaming Layer.
|
||||
The Symbol layer is based on my Planck layout. It provides numbers, symbols, and volume controls.
|
||||
There are two Navigation layers, for the Mac and Windows Colemak layers respectively.
|
@ -0,0 +1,148 @@
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
#include "alt.h"
|
||||
|
||||
#include "led_matrix.h"
|
||||
#include "rgb_matrix.h"
|
||||
#include "config_led.h"
|
||||
|
||||
// This table can be almost-automatically derived from ISSI3733_LED_MAP that is
|
||||
// defined in config_led.h
|
||||
|
||||
// You can calculate the (0-244, 0-64) x/y values from the x/y values defined in
|
||||
// ISSI3733_LED_MAP with the following formula:
|
||||
// uint8_t rgb_x = ((ISSI3733_LED_MAP[i].x - MIN_X) / (MAX_X - MIN_X)) * 224;
|
||||
// uint8_t rgb_y = ((ISSI3733_LED_MAP[i].y - MIN_Y) / (MAX_Y - MIN_Y)) * 64;
|
||||
// Where the min/max vars are the minimum and maximum "bounds" of x/y values
|
||||
// present in ISSI3733_LED_MAP
|
||||
//
|
||||
// The row/col values need to be manually tweaked though, compensating for the
|
||||
// "empty" cells that are a product of larger keys
|
||||
//
|
||||
// There is a quick-and-dirty implementation of this under ledvis.html
|
||||
|
||||
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
|
||||
/* 0 */ { { (0)|(0 << 4) }, { 8, 56 }, 0 }, // KC_ESC
|
||||
/* 1 */ { { (0)|(1 << 4) }, { 22, 56 }, 0 }, // KC_1
|
||||
/* 2 */ { { (0)|(2 << 4) }, { 35, 56 }, 0 }, // KC_2
|
||||
/* 3 */ { { (0)|(3 << 4) }, { 49, 56 }, 0 }, // KC_3
|
||||
/* 4 */ { { (0)|(4 << 4) }, { 63, 56 }, 0 }, // KC_4
|
||||
/* 5 */ { { (0)|(5 << 4) }, { 77, 56 }, 0 }, // KC_5
|
||||
/* 6 */ { { (0)|(6 << 4) }, { 91, 56 }, 0 }, // KC_6
|
||||
/* 7 */ { { (0)|(7 << 4) }, { 105, 56 }, 0 }, // KC_7
|
||||
/* 8 */ { { (0)|(8 << 4) }, { 118, 56 }, 0 }, // KC_8
|
||||
/* 9 */ { { (0)|(9 << 4) }, { 132, 56 }, 0 }, // KC_9
|
||||
/* 10 */ { { (0)|(10 << 4) }, { 146, 56 }, 0 }, // KC_0
|
||||
/* 11 */ { { (0)|(11 << 4) }, { 160, 56 }, 0 }, // KC_MINS
|
||||
/* 12 */ { { (0)|(12 << 4) }, { 174, 56 }, 0 }, // KC_EQL
|
||||
/* 13 */ { { (0)|(13 << 4) }, { 195, 56 }, 0 }, // KC_BSPC
|
||||
/* 14 */ { { (0)|(14 << 4) }, { 215, 56 }, 0 }, // KC_DEL
|
||||
/* 15 */ { { (1)|(0 << 4) }, { 11, 44 }, 0 }, // KC_TAB
|
||||
/* 16 */ { { (1)|(1 << 4) }, { 28, 44 }, 0 }, // KC_Q
|
||||
/* 17 */ { { (1)|(2 << 4) }, { 42, 44 }, 0 }, // KC_W
|
||||
/* 18 */ { { (1)|(3 << 4) }, { 56, 44 }, 0 }, // KC_E
|
||||
/* 19 */ { { (1)|(4 << 4) }, { 70, 44 }, 0 }, // KC_R
|
||||
/* 20 */ { { (1)|(5 << 4) }, { 84, 44 }, 0 }, // KC_T
|
||||
/* 21 */ { { (1)|(6 << 4) }, { 98, 44 }, 0 }, // KC_Y
|
||||
/* 22 */ { { (1)|(7 << 4) }, { 112, 44 }, 0 }, // KC_U
|
||||
/* 23 */ { { (1)|(8 << 4) }, { 125, 44 }, 0 }, // KC_I
|
||||
/* 24 */ { { (1)|(9 << 4) }, { 139, 44 }, 0 }, // KC_O
|
||||
/* 25 */ { { (1)|(10 << 4) }, { 153, 44 }, 0 }, // KC_P
|
||||
/* 26 */ { { (1)|(11 << 4) }, { 167, 44 }, 0 }, // KC_LBRC
|
||||
/* 27 */ { { (1)|(12 << 4) }, { 181, 44 }, 0 }, // KC_RBRC
|
||||
/* 28 */ { { (1)|(13 << 4) }, { 198, 44 }, 0 }, // KC_BSLS
|
||||
/* 29 */ { { (1)|(14 << 4) }, { 215, 44 }, 0 }, // KC_HOME
|
||||
/* 30 */ { { (2)|(0 << 4) }, { 13, 32 }, 1 }, // KC_CAPS
|
||||
/* 31 */ { { (2)|(1 << 4) }, { 32, 32 }, 0 }, // KC_A
|
||||
/* 32 */ { { (2)|(2 << 4) }, { 46, 32 }, 0 }, // KC_S
|
||||
/* 33 */ { { (2)|(3 << 4) }, { 60, 32 }, 0 }, // KC_D
|
||||
/* 34 */ { { (2)|(4 << 4) }, { 73, 32 }, 0 }, // KC_F
|
||||
/* 35 */ { { (2)|(5 << 4) }, { 87, 32 }, 0 }, // KC_G
|
||||
/* 36 */ { { (2)|(6 << 4) }, { 101, 32 }, 0 }, // KC_H
|
||||
/* 37 */ { { (2)|(7 << 4) }, { 115, 32 }, 0 }, // KC_J
|
||||
/* 38 */ { { (2)|(8 << 4) }, { 129, 32 }, 0 }, // KC_K
|
||||
/* 39 */ { { (2)|(9 << 4) }, { 143, 32 }, 0 }, // KC_L
|
||||
/* 40 */ { { (2)|(10 << 4) }, { 156, 32 }, 0 }, // KC_SCLN
|
||||
/* 41 */ { { (2)|(11 << 4) }, { 170, 32 }, 0 }, // KC_QUOT
|
||||
/* _________________________________________ */ // ____
|
||||
/* 42 */ { { (2)|(13 << 4) }, { 193, 32 }, 0 }, // KC_ENT
|
||||
/* 43 */ { { (2)|(14 << 4) }, { 215, 32 }, 0 }, // KC_PGUP
|
||||
/* 44 */ { { (3)|(0 << 4) }, { 16, 19 }, 0 }, // KC_LSFT
|
||||
/* 45 */ { { (3)|(2 << 4) }, { 39, 19 }, 0 }, // KC_Z
|
||||
/* 46 */ { { (3)|(3 << 4) }, { 53, 19 }, 0 }, // KC_X
|
||||
/* 47 */ { { (3)|(4 << 4) }, { 67, 19 }, 0 }, // KC_C
|
||||
/* 48 */ { { (3)|(5 << 4) }, { 80, 19 }, 0 }, // KC_V
|
||||
/* 49 */ { { (3)|(6 << 4) }, { 94, 19 }, 0 }, // KC_B
|
||||
/* 50 */ { { (3)|(7 << 4) }, { 108, 19 }, 0 }, // KC_N
|
||||
/* 51 */ { { (3)|(8 << 4) }, { 122, 19 }, 0 }, // KC_M
|
||||
/* 52 */ { { (3)|(9 << 4) }, { 136, 19 }, 0 }, // KC_COMM
|
||||
/* 53 */ { { (3)|(10 << 4) }, { 150, 19 }, 0 }, // KC_DOT
|
||||
/* 54 */ { { (3)|(11 << 4) }, { 163, 19 }, 0 }, // KC_SLSH
|
||||
/* 55 */ { { (3)|(12 << 4) }, { 182, 19 }, 0 }, // KC_RSFT
|
||||
/* _________________________________________ */ // ____
|
||||
/* 56 */ { { (3)|(13 << 4) }, { 201, 19 }, 0 }, // KC_UP
|
||||
/* 57 */ { { (3)|(14 << 4) }, { 215, 19 }, 0 }, // KC_PGDN
|
||||
/* 58 */ { { (4)|(0 << 4) }, { 9, 7 }, 0 }, // KC_LCTL
|
||||
/* 59 */ { { (4)|(1 << 4) }, { 27, 7 }, 0 }, // KC_LGUI
|
||||
/* 60 */ { { (4)|(2 << 4) }, { 44, 7 }, 0 }, // KC_LALT
|
||||
/* _________________________________________ */ // ____
|
||||
/* _________________________________________ */ // ____
|
||||
/* _________________________________________ */ // ____
|
||||
/* 61 */ { { (4)|(6 << 4) }, { 96, 7 }, 0 }, // KC_SPC
|
||||
/* _________________________________________ */ // ____
|
||||
/* _________________________________________ */ // ____
|
||||
/* _________________________________________ */ // ____
|
||||
/* 62 */ { { (4)|(10 << 4) }, { 148, 7 }, 0 }, // KC_RALT
|
||||
/* 63 */ { { (4)|(11 << 4) }, { 165, 7 }, 0 }, // MO(1)
|
||||
/* 64 */ { { (4)|(12 << 4) }, { 188, 7 }, 0 }, // KC_LEFT
|
||||
/* 65 */ { { (4)|(13 << 4) }, { 201, 7 }, 0 }, // KC_DOWN
|
||||
/* 66 */ { { (4)|(14 << 4) }, { 215, 7 }, 0 }, // KC_RGHT
|
||||
|
||||
// Underglow LEDs
|
||||
{ { 255 }, { 1, 1 }, 0 },
|
||||
{ { 255 }, { 15, 0 }, 0 },
|
||||
{ { 255 }, { 31, 0 }, 0 },
|
||||
{ { 255 }, { 47, 0 }, 0 },
|
||||
{ { 255 }, { 63, 0 }, 0 },
|
||||
{ { 255 }, { 79, 0 }, 0 },
|
||||
{ { 255 }, { 95, 0 }, 0 },
|
||||
{ { 255 }, { 112, 0 }, 0 },
|
||||
{ { 255 }, { 128, 0 }, 0 },
|
||||
{ { 255 }, { 144, 0 }, 0 },
|
||||
{ { 255 }, { 160, 0 }, 0 },
|
||||
{ { 255 }, { 176, 0 }, 0 },
|
||||
{ { 255 }, { 192, 0 }, 0 },
|
||||
{ { 255 }, { 208, 0 }, 0 },
|
||||
{ { 255 }, { 222, 1 }, 0 },
|
||||
{ { 255 }, { 224, 13 }, 0 },
|
||||
{ { 255 }, { 224, 25 }, 0 },
|
||||
{ { 255 }, { 224, 38 }, 0 },
|
||||
{ { 255 }, { 224, 50 }, 0 },
|
||||
{ { 255 }, { 222, 62 }, 0 },
|
||||
{ { 255 }, { 191, 64 }, 0 },
|
||||
{ { 255 }, { 179, 64 }, 0 },
|
||||
{ { 255 }, { 167, 64 }, 0 },
|
||||
{ { 255 }, { 153, 64 }, 0 },
|
||||
{ { 255 }, { 139, 64 }, 0 },
|
||||
{ { 255 }, { 125, 64 }, 0 },
|
||||
{ { 255 }, { 112, 64 }, 0 },
|
||||
{ { 255 }, { 98, 64 }, 0 },
|
||||
{ { 255 }, { 84, 64 }, 0 },
|
||||
{ { 255 }, { 70, 64 }, 0 },
|
||||
{ { 255 }, { 56, 64 }, 0 },
|
||||
{ { 255 }, { 42, 64 }, 0 },
|
||||
{ { 255 }, { 28, 64 }, 0 },
|
||||
{ { 255 }, { 1, 62 }, 0 },
|
||||
{ { 255 }, { 0, 50 }, 0 },
|
||||
{ { 255 }, { 0, 38 }, 0 },
|
||||
{ { 255 }, { 0, 25 }, 0 },
|
||||
{ { 255 }, { 0, 13 }, 0 },
|
||||
};
|
||||
|
||||
#ifdef USB_LED_INDICATOR_ENABLE
|
||||
void rgb_matrix_indicators_kb(void)
|
||||
{
|
||||
led_matrix_indicators();
|
||||
}
|
||||
#endif // USB_LED_INDICATOR_ENABLE
|
||||
|
||||
#endif
|
@ -0,0 +1,223 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum alt_keycodes {
|
||||
L_BRI = SAFE_RANGE, //LED Brightness Increase //Working
|
||||
L_BRD, //LED Brightness Decrease //Working
|
||||
L_PTN, //LED Pattern Select Next //Working
|
||||
L_PTP, //LED Pattern Select Previous //Working
|
||||
L_PSI, //LED Pattern Speed Increase //Working
|
||||
L_PSD, //LED Pattern Speed Decrease //Working
|
||||
L_T_MD, //LED Toggle Mode //Working
|
||||
L_T_ONF, //LED Toggle On / Off //Broken
|
||||
L_ON, //LED On //Broken
|
||||
L_OFF, //LED Off //Broken
|
||||
L_T_BR, //LED Toggle Breath Effect //Working
|
||||
L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working
|
||||
U_T_AGCR, //USB Toggle Automatic GCR control //Working
|
||||
DBG_TOG, //DEBUG Toggle On / Off //
|
||||
DBG_MTRX, //DEBUG Toggle Matrix Prints //
|
||||
DBG_KBD, //DEBUG Toggle Keyboard Prints //
|
||||
DBG_MOU, //DEBUG Toggle Mouse Prints //
|
||||
MD_BOOT //Restart into bootloader after hold timeout //Working
|
||||
};
|
||||
|
||||
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
|
||||
|
||||
keymap_config_t keymap_config;
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, \
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, \
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, \
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT \
|
||||
),
|
||||
[1] = LAYOUT(
|
||||
KC_GRV, 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_MUTE, \
|
||||
L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \
|
||||
L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \
|
||||
_______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \
|
||||
_______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \
|
||||
),
|
||||
/*
|
||||
[X] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
*/
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void matrix_init_user(void) {
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void matrix_scan_user(void) {
|
||||
};
|
||||
|
||||
#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
|
||||
#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
|
||||
#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
static uint32_t key_timer;
|
||||
|
||||
switch (keycode) {
|
||||
case L_BRI:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX;
|
||||
else gcr_desired += LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_BRD:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > gcr_desired) gcr_desired = 0;
|
||||
else gcr_desired -= LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_PTN:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == led_setups_count - 1) led_animation_id = 0;
|
||||
else led_animation_id++;
|
||||
}
|
||||
return false;
|
||||
case L_PTP:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == 0) led_animation_id = led_setups_count - 1;
|
||||
else led_animation_id--;
|
||||
}
|
||||
return false;
|
||||
case L_PSI:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed += ANIMATION_SPEED_STEP;
|
||||
}
|
||||
return false;
|
||||
case L_PSD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed -= ANIMATION_SPEED_STEP;
|
||||
if (led_animation_speed < 0) led_animation_speed = 0;
|
||||
}
|
||||
return false;
|
||||
case L_T_MD:
|
||||
if (record->event.pressed) {
|
||||
led_lighting_mode++;
|
||||
if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
case L_T_ONF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = !led_enabled;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_ON:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 1;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_OFF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 0;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_T_BR:
|
||||
if (record->event.pressed) {
|
||||
led_animation_breathing = !led_animation_breathing;
|
||||
if (led_animation_breathing) {
|
||||
gcr_breathe = gcr_desired;
|
||||
led_animation_breathe_cur = BREATHE_MIN_STEP;
|
||||
breathe_dir = 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case L_T_PTD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_direction = !led_animation_direction;
|
||||
}
|
||||
return false;
|
||||
case U_T_AGCR:
|
||||
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
|
||||
TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_TOG:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_MTRX:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
|
||||
}
|
||||
return false;
|
||||
case DBG_KBD:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
|
||||
}
|
||||
return false;
|
||||
case DBG_MOU:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
|
||||
}
|
||||
return false;
|
||||
case MD_BOOT:
|
||||
if (record->event.pressed) {
|
||||
key_timer = timer_read32();
|
||||
} else {
|
||||
if (timer_elapsed32(key_timer) >= 500) {
|
||||
reset_keyboard();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return true; //Process all other keycodes normally
|
||||
}
|
||||
}
|
||||
|
||||
led_instruction_t led_instructions[] = {
|
||||
//LEDs are normally inactive, no processing is performed on them
|
||||
//Flags are used in matching criteria for an LED to be active and indicate how to color it
|
||||
//Flags can be found in tmk_core/protocol/arm_atsam/led_matrix.h (prefixed with LED_FLAG_)
|
||||
//LED IDs can be found in config_led.h in the keyboard's directory
|
||||
//Examples are below
|
||||
|
||||
//All LEDs use the user's selected pattern (this is the factory default)
|
||||
{ .flags = LED_FLAG_USE_ROTATE_PATTERN },
|
||||
|
||||
//Specific LEDs use the user's selected pattern while all others are off
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 0xFFFFFFFF, .id1 = 0xAAAAAAAA, .id2 = 0x55555555, .id3 = 0x11111111 },
|
||||
|
||||
//Specific LEDs use specified RGB values while all others are off
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFF, .id1 = 0x00FF, .id2 = 0x0000FF00, .id3 = 0xFF000000, .r = 75, .g = 150, .b = 225 },
|
||||
|
||||
//All LEDs use the user's selected pattern
|
||||
//On layer 1, all key LEDs (except the top row which keeps active pattern) are red while all edge LEDs are green
|
||||
//When layer 1 is active, key LEDs use red (id0 32 - 16: 1111 1111 1111 1111 1000 0000 0000 0000 = 0xFFFF8000) (except top row 15 - 1)
|
||||
//When layer 1 is active, key LEDs use red (id1 64 - 33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
|
||||
//When layer 1 is active, key LEDs use red (id2 67 - 65: 0000 0000 0000 0000 0000 0000 0000 0111 = 0x00000007)
|
||||
//When layer 1 is active, edge LEDs use green (id2 95 - 68: 1111 1111 1111 1111 1111 1111 1111 1000 = 0xFFFFFFF8)
|
||||
//When layer 1 is active, edge LEDs use green (id3 105 - 96: 0000 0000 0000 0000 0000 0011 1111 1111 = 0x000003FF)
|
||||
// { .flags = LED_FLAG_USE_ROTATE_PATTERN },
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_RGB, .id0 = 0xFFFF8000, .id1 = 0xFFFFFFFF, .id2 = 0x00000007, .r = 255, .layer = 1 },
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_RGB, .id2 = 0xFFFFFFF8, .id3 = 0x000003FF, .g = 127, .layer = 1 },
|
||||
|
||||
//All key LEDs use red while edge LEDs use the active pattern
|
||||
//All key LEDs use red (id0 32 - 1: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
|
||||
//All key LEDs use red (id1 64 - 33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
|
||||
//All key LEDs use red (id2 67 - 65: 0000 0000 0000 0000 0000 0000 0000 0111 = 0x00000007)
|
||||
//Edge uses active pattern (id2 95 - 68: 1111 1111 1111 1111 1111 1111 1111 1000 = 0xFFFFFFF8)
|
||||
//Edge uses active pattern (id3 105 - 96: 0000 0000 0000 0000 0000 0011 1111 1111 = 0x000003FF)
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFFFFFFFF, .id1 = 0xFFFFFFFF, .id2 = 0x00000007, .r = 255 },
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN , .id2 = 0xFFFFFFF8, .id3 = 0x000003FF },
|
||||
|
||||
//end must be set to 1 to indicate end of instruction set
|
||||
{ .end = 1 }
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
# This keymap requires Massdrop Configurator support
|
||||
OPT_DEFS += -DUSE_MASSDROP_CONFIGURATOR
|
@ -0,0 +1,193 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum alt_keycodes {
|
||||
L_BRI = SAFE_RANGE, //LED Brightness Increase //Working
|
||||
L_BRD, //LED Brightness Decrease //Working
|
||||
L_PTN, //LED Pattern Select Next //Working
|
||||
L_PTP, //LED Pattern Select Previous //Working
|
||||
L_PSI, //LED Pattern Speed Increase //Working
|
||||
L_PSD, //LED Pattern Speed Decrease //Working
|
||||
L_T_MD, //LED Toggle Mode //Working
|
||||
L_T_ONF, //LED Toggle On / Off //Broken
|
||||
L_ON, //LED On //Broken
|
||||
L_OFF, //LED Off //Broken
|
||||
L_T_BR, //LED Toggle Breath Effect //Working
|
||||
L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working
|
||||
U_T_AGCR, //USB Toggle Automatic GCR control //Working
|
||||
DBG_TOG, //DEBUG Toggle On / Off //
|
||||
DBG_MTRX, //DEBUG Toggle Matrix Prints //
|
||||
DBG_KBD, //DEBUG Toggle Keyboard Prints //
|
||||
DBG_MOU, //DEBUG Toggle Mouse Prints //
|
||||
MD_BOOT //Restart into bootloader after hold timeout //Working
|
||||
};
|
||||
|
||||
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
|
||||
|
||||
keymap_config_t keymap_config;
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, \
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, \
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, \
|
||||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_LEFT, KC_DOWN, KC_RGHT \
|
||||
),
|
||||
[1] = LAYOUT(
|
||||
KC_GRV, 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_MUTE, \
|
||||
L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \
|
||||
L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \
|
||||
_______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \
|
||||
_______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \
|
||||
),
|
||||
/*
|
||||
[X] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
*/
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void matrix_init_user(void) {
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void matrix_scan_user(void) {
|
||||
};
|
||||
|
||||
#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
|
||||
#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
|
||||
#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
static uint32_t key_timer;
|
||||
|
||||
switch (keycode) {
|
||||
case L_BRI:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX;
|
||||
else gcr_desired += LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_BRD:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > gcr_desired) gcr_desired = 0;
|
||||
else gcr_desired -= LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_PTN:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == led_setups_count - 1) led_animation_id = 0;
|
||||
else led_animation_id++;
|
||||
}
|
||||
return false;
|
||||
case L_PTP:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == 0) led_animation_id = led_setups_count - 1;
|
||||
else led_animation_id--;
|
||||
}
|
||||
return false;
|
||||
case L_PSI:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed += ANIMATION_SPEED_STEP;
|
||||
}
|
||||
return false;
|
||||
case L_PSD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed -= ANIMATION_SPEED_STEP;
|
||||
if (led_animation_speed < 0) led_animation_speed = 0;
|
||||
}
|
||||
return false;
|
||||
case L_T_MD:
|
||||
if (record->event.pressed) {
|
||||
led_lighting_mode++;
|
||||
if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
case L_T_ONF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = !led_enabled;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_ON:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 1;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_OFF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 0;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_T_BR:
|
||||
if (record->event.pressed) {
|
||||
led_animation_breathing = !led_animation_breathing;
|
||||
if (led_animation_breathing) {
|
||||
gcr_breathe = gcr_desired;
|
||||
led_animation_breathe_cur = BREATHE_MIN_STEP;
|
||||
breathe_dir = 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case L_T_PTD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_direction = !led_animation_direction;
|
||||
}
|
||||
return false;
|
||||
case U_T_AGCR:
|
||||
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
|
||||
TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_TOG:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_MTRX:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
|
||||
}
|
||||
return false;
|
||||
case DBG_KBD:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
|
||||
}
|
||||
return false;
|
||||
case DBG_MOU:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
|
||||
}
|
||||
return false;
|
||||
case MD_BOOT:
|
||||
if (record->event.pressed) {
|
||||
key_timer = timer_read32();
|
||||
} else {
|
||||
if (timer_elapsed32(key_timer) >= 500) {
|
||||
reset_keyboard();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return true; //Process all other keycodes normally
|
||||
}
|
||||
}
|
||||
|
||||
led_instruction_t led_instructions[] = {
|
||||
//Please see ../default_md/keymap.c for examples
|
||||
|
||||
//All LEDs use the user's selected pattern (this is the factory default)
|
||||
{ .flags = LED_FLAG_USE_ROTATE_PATTERN },
|
||||
|
||||
//end must be set to 1 to indicate end of instruction set
|
||||
{ .end = 1 }
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
# This keymap requires Massdrop Configurator support
|
||||
OPT_DEFS += -DUSE_MASSDROP_CONFIGURATOR
|
@ -0,0 +1,5 @@
|
||||
# THIS KEYMAP IS BROKEN
|
||||
|
||||
The CTRL and ALT have both been switched to using the QMK RGB Matrix system,
|
||||
rendering any custom effects that used the old, custom Massdrop lighting system,
|
||||
BROKEN.
|
@ -0,0 +1,144 @@
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
#include "ctrl.h"
|
||||
|
||||
#include "led_matrix.h"
|
||||
#include "rgb_matrix.h"
|
||||
#include "config_led.h"
|
||||
|
||||
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
|
||||
// KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS
|
||||
{ { 0|(0<<4) }, { 7, 5 }, 0 },
|
||||
{ { 0|(1<<4) }, { 31, 5 }, 0 },
|
||||
{ { 0|(2<<4) }, { 43, 5 }, 0 },
|
||||
{ { 0|(3<<4) }, { 55, 5 }, 0 },
|
||||
{ { 0|(4<<4) }, { 67, 5 }, 0 },
|
||||
{ { 0|(5<<4) }, { 85, 5 }, 0 },
|
||||
{ { 0|(6<<4) }, { 97, 5 }, 0 },
|
||||
{ { 0|(7<<4) }, { 109, 5 }, 0 },
|
||||
{ { 6|(0<<4) }, { 121, 5 }, 0 },
|
||||
{ { 6|(1<<4) }, { 139, 5 }, 0 },
|
||||
{ { 6|(2<<4) }, { 151, 5 }, 0 },
|
||||
{ { 6|(3<<4) }, { 163, 5 }, 0 },
|
||||
{ { 6|(4<<4) }, { 175, 5 }, 0 },
|
||||
{ { 6|(5<<4) }, { 193, 5 }, 0 },
|
||||
{ { 6|(6<<4) }, { 205, 5 }, 1 },
|
||||
{ { 6|(7<<4) }, { 217, 5 }, 0 },
|
||||
// KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP
|
||||
{ { 1|(0<<4) }, { 7, 20 }, 0 },
|
||||
{ { 1|(1<<4) }, { 19, 20 }, 0 },
|
||||
{ { 1|(2<<4) }, { 31, 20 }, 0 },
|
||||
{ { 1|(3<<4) }, { 43, 20 }, 0 },
|
||||
{ { 1|(4<<4) }, { 55, 20 }, 0 },
|
||||
{ { 1|(5<<4) }, { 67, 20 }, 0 },
|
||||
{ { 1|(6<<4) }, { 79, 20 }, 0 },
|
||||
{ { 1|(7<<4) }, { 91, 20 }, 0 },
|
||||
{ { 7|(0<<4) }, { 103, 20 }, 0 },
|
||||
{ { 7|(1<<4) }, { 115, 20 }, 0 },
|
||||
{ { 7|(2<<4) }, { 127, 20 }, 0 },
|
||||
{ { 7|(3<<4) }, { 139, 20 }, 0 },
|
||||
{ { 7|(4<<4) }, { 151, 20 }, 0 },
|
||||
{ { 7|(5<<4) }, { 169, 20 }, 0 },
|
||||
{ { 7|(6<<4) }, { 193, 20 }, 0 },
|
||||
{ { 7|(7<<4) }, { 205, 20 }, 0 },
|
||||
{ { 9|(7<<4) }, { 217, 20 }, 0 },
|
||||
// KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN
|
||||
{ { 2|(0<<4) }, { 10, 30 }, 0 },
|
||||
{ { 2|(1<<4) }, { 25, 30 }, 0 },
|
||||
{ { 2|(2<<4) }, { 37, 30 }, 0 },
|
||||
{ { 2|(3<<4) }, { 49, 30 }, 0 },
|
||||
{ { 2|(4<<4) }, { 61, 30 }, 0 },
|
||||
{ { 2|(5<<4) }, { 73, 30 }, 0 },
|
||||
{ { 2|(6<<4) }, { 85, 30 }, 0 },
|
||||
{ { 2|(7<<4) }, { 97, 30 }, 0 },
|
||||
{ { 8|(0<<4) }, { 109, 30 }, 0 },
|
||||
{ { 8|(1<<4) }, { 121, 30 }, 0 },
|
||||
{ { 8|(2<<4) }, { 133, 30 }, 0 },
|
||||
{ { 8|(3<<4) }, { 145, 30 }, 0 },
|
||||
{ { 8|(4<<4) }, { 157, 30 }, 0 },
|
||||
{ { 8|(5<<4) }, { 172, 30 }, 0 },
|
||||
{ { 8|(6<<4) }, { 193, 30 }, 0 },
|
||||
{ { 8|(7<<4) }, { 205, 30 }, 0 },
|
||||
{ { 9|(6<<4) }, { 217, 30 }, 0 },
|
||||
// KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT
|
||||
{ { 3|(0<<4) }, { 11, 39 }, 1 },
|
||||
{ { 3|(1<<4) }, { 28, 39 }, 0 },
|
||||
{ { 3|(2<<4) }, { 40, 39 }, 0 },
|
||||
{ { 3|(3<<4) }, { 52, 39 }, 0 },
|
||||
{ { 3|(4<<4) }, { 64, 39 }, 0 },
|
||||
{ { 3|(5<<4) }, { 76, 39 }, 0 },
|
||||
{ { 3|(6<<4) }, { 88, 39 }, 0 },
|
||||
{ { 3|(7<<4) }, { 100, 39 }, 0 },
|
||||
{ { 9|(0<<4) }, { 112, 39 }, 0 },
|
||||
{ { 9|(1<<4) }, { 124, 39 }, 0 },
|
||||
{ { 9|(2<<4) }, { 136, 39 }, 0 },
|
||||
{ { 9|(3<<4) }, { 148, 39 }, 0 },
|
||||
{ { 9|(4<<4) }, { 168, 39 }, 0 },
|
||||
// KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP
|
||||
{ { 4|(0<<4) }, { 14, 49 }, 0 },
|
||||
{ { 4|(1<<4) }, { 34, 49 }, 0 },
|
||||
{ { 4|(2<<4) }, { 46, 49 }, 0 },
|
||||
{ { 4|(3<<4) }, { 58, 49 }, 0 },
|
||||
{ { 4|(4<<4) }, { 70, 49 }, 0 },
|
||||
{ { 4|(5<<4) }, { 82, 49 }, 0 },
|
||||
{ { 4|(6<<4) }, { 94, 49 }, 0 },
|
||||
{ { 4|(7<<4) }, { 106, 49 }, 0 },
|
||||
{ { 10|(0<<4) }, { 118, 49 }, 0 },
|
||||
{ { 10|(1<<4) }, { 130, 49 }, 0 },
|
||||
{ { 10|(2<<4) }, { 142, 49 }, 0 },
|
||||
{ { 10|(3<<4) }, { 165, 49 }, 0 },
|
||||
{ { 9|(5<<4) }, { 205, 49 }, 0 },
|
||||
// KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
|
||||
{ { 5|(0<<4) }, { 8, 59 }, 0 },
|
||||
{ { 5|(1<<4) }, { 23, 59 }, 0 },
|
||||
{ { 5|(2<<4) }, { 38, 59 }, 0 },
|
||||
{ { 5|(3<<4) }, { 83, 59 }, 0 },
|
||||
{ { 5|(4<<4) }, { 129, 59 }, 0 },
|
||||
{ { 5|(5<<4) }, { 144, 59 }, 0 },
|
||||
{ { 5|(6<<4) }, { 159, 59 }, 0 },
|
||||
{ { 5|(7<<4) }, { 174, 59 }, 0 },
|
||||
{ { 10|(4<<4) }, { 193, 59 }, 0 },
|
||||
{ { 10|(5<<4) }, { 205, 59 }, 0 },
|
||||
{ { 10|(6<<4) }, { 217, 59 }, 0 },
|
||||
// Underglow / Border
|
||||
{ { 0xFF }, { 222, 64 }, 0 },
|
||||
{ { 0xFF }, { 204, 64 }, 0 },
|
||||
{ { 0xFF }, { 186, 64 }, 0 },
|
||||
{ { 0xFF }, { 167, 64 }, 0 },
|
||||
{ { 0xFF }, { 149, 64 }, 0 },
|
||||
{ { 0xFF }, { 130, 64 }, 0 },
|
||||
{ { 0xFF }, { 112, 64 }, 0 },
|
||||
{ { 0xFF }, { 94, 64 }, 0 },
|
||||
{ { 0xFF }, { 75, 64 }, 0 },
|
||||
{ { 0xFF }, { 57, 64 }, 0 },
|
||||
{ { 0xFF }, { 38, 64 }, 0 },
|
||||
{ { 0xFF }, { 20, 64 }, 0 },
|
||||
{ { 0xFF }, { 0, 64 }, 0 },
|
||||
{ { 0xFF }, { 0, 47 }, 0 },
|
||||
{ { 0xFF }, { 0, 32 }, 0 },
|
||||
{ { 0xFF }, { 0, 17 }, 0 },
|
||||
{ { 0xFF }, { 0, 0 }, 0 },
|
||||
{ { 0xFF }, { 20, 0 }, 0 },
|
||||
{ { 0xFF }, { 38, 0 }, 0 },
|
||||
{ { 0xFF }, { 57, 0 }, 0 },
|
||||
{ { 0xFF }, { 75, 0 }, 0 },
|
||||
{ { 0xFF }, { 94, 0 }, 0 },
|
||||
{ { 0xFF }, { 112, 0 }, 0 },
|
||||
{ { 0xFF }, { 130, 0 }, 0 },
|
||||
{ { 0xFF }, { 149, 0 }, 0 },
|
||||
{ { 0xFF }, { 167, 0 }, 0 },
|
||||
{ { 0xFF }, { 186, 0 }, 0 },
|
||||
{ { 0xFF }, { 204, 0 }, 0 },
|
||||
{ { 0xFF }, { 222, 1 }, 0 },
|
||||
{ { 0xFF }, { 224, 17 }, 0 },
|
||||
{ { 0xFF }, { 224, 32 }, 0 },
|
||||
{ { 0xFF }, { 224, 47 }, 0 },
|
||||
};
|
||||
|
||||
#ifdef USB_LED_INDICATOR_ENABLE
|
||||
void rgb_matrix_indicators_kb(void)
|
||||
{
|
||||
led_matrix_indicators();
|
||||
}
|
||||
#endif // USB_LED_INDICATOR_ENABLE
|
||||
|
||||
#endif
|
@ -0,0 +1,226 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum ctrl_keycodes {
|
||||
L_BRI = SAFE_RANGE, //LED Brightness Increase //Working
|
||||
L_BRD, //LED Brightness Decrease //Working
|
||||
L_PTN, //LED Pattern Select Next //Working
|
||||
L_PTP, //LED Pattern Select Previous //Working
|
||||
L_PSI, //LED Pattern Speed Increase //Working
|
||||
L_PSD, //LED Pattern Speed Decrease //Working
|
||||
L_T_MD, //LED Toggle Mode //Working
|
||||
L_T_ONF, //LED Toggle On / Off //Broken
|
||||
L_ON, //LED On //Broken
|
||||
L_OFF, //LED Off //Broken
|
||||
L_T_BR, //LED Toggle Breath Effect //Working
|
||||
L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working
|
||||
U_T_AGCR, //USB Toggle Automatic GCR control //Working
|
||||
DBG_TOG, //DEBUG Toggle On / Off //
|
||||
DBG_MTRX, //DEBUG Toggle Matrix Prints //
|
||||
DBG_KBD, //DEBUG Toggle Keyboard Prints //
|
||||
DBG_MOU, //DEBUG Toggle Mouse Prints //
|
||||
MD_BOOT //Restart into bootloader after hold timeout //Working
|
||||
};
|
||||
|
||||
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
|
||||
|
||||
keymap_config_t keymap_config;
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = 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_PSCR, KC_SLCK, KC_PAUS, \
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
|
||||
),
|
||||
[1] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \
|
||||
L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \
|
||||
L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
/*
|
||||
[X] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
*/
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void matrix_init_user(void) {
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void matrix_scan_user(void) {
|
||||
};
|
||||
|
||||
#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
|
||||
#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
|
||||
#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
static uint32_t key_timer;
|
||||
|
||||
switch (keycode) {
|
||||
case L_BRI:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX;
|
||||
else gcr_desired += LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_BRD:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > gcr_desired) gcr_desired = 0;
|
||||
else gcr_desired -= LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_PTN:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == led_setups_count - 1) led_animation_id = 0;
|
||||
else led_animation_id++;
|
||||
}
|
||||
return false;
|
||||
case L_PTP:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == 0) led_animation_id = led_setups_count - 1;
|
||||
else led_animation_id--;
|
||||
}
|
||||
return false;
|
||||
case L_PSI:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed += ANIMATION_SPEED_STEP;
|
||||
}
|
||||
return false;
|
||||
case L_PSD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed -= ANIMATION_SPEED_STEP;
|
||||
if (led_animation_speed < 0) led_animation_speed = 0;
|
||||
}
|
||||
return false;
|
||||
case L_T_MD:
|
||||
if (record->event.pressed) {
|
||||
led_lighting_mode++;
|
||||
if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
case L_T_ONF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = !led_enabled;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_ON:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 1;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_OFF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 0;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_T_BR:
|
||||
if (record->event.pressed) {
|
||||
led_animation_breathing = !led_animation_breathing;
|
||||
if (led_animation_breathing) {
|
||||
gcr_breathe = gcr_desired;
|
||||
led_animation_breathe_cur = BREATHE_MIN_STEP;
|
||||
breathe_dir = 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case L_T_PTD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_direction = !led_animation_direction;
|
||||
}
|
||||
return false;
|
||||
case U_T_AGCR:
|
||||
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
|
||||
TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_TOG:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_MTRX:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
|
||||
}
|
||||
return false;
|
||||
case DBG_KBD:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
|
||||
}
|
||||
return false;
|
||||
case DBG_MOU:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
|
||||
}
|
||||
return false;
|
||||
case MD_BOOT:
|
||||
if (record->event.pressed) {
|
||||
key_timer = timer_read32();
|
||||
} else {
|
||||
if (timer_elapsed32(key_timer) >= 500) {
|
||||
reset_keyboard();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return true; //Process all other keycodes normally
|
||||
}
|
||||
}
|
||||
|
||||
led_instruction_t led_instructions[] = {
|
||||
//LEDs are normally inactive, no processing is performed on them
|
||||
//Flags are used in matching criteria for an LED to be active and indicate how to color it
|
||||
//Flags can be found in tmk_core/protocol/arm_atsam/led_matrix.h (prefixed with LED_FLAG_)
|
||||
//LED IDs can be found in config_led.h in the keyboard's directory
|
||||
//Examples are below
|
||||
|
||||
//All LEDs use the user's selected pattern (this is the factory default)
|
||||
{ .flags = LED_FLAG_USE_ROTATE_PATTERN },
|
||||
|
||||
//Specific LEDs use the user's selected pattern while all others are off
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 0xFFFFFFFF, .id1 = 0xAAAAAAAA, .id2 = 0x55555555, .id3 = 0x11111111 },
|
||||
|
||||
//Specific LEDs use specified RGB values while all others are off
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFF, .id1 = 0x00FF, .id2 = 0x0000FF00, .id3 = 0xFF000000, .r = 75, .g = 150, .b = 225 },
|
||||
|
||||
//All LEDs use the user's selected pattern
|
||||
//On layer 1, all key LEDs (except the top row which keeps active pattern) are red while all edge LEDs are green
|
||||
//When layer 1 is active, key LEDs use red (id0 32 - 17: 1111 1111 1111 1111 0000 0000 0000 0000 = 0xFFFF0000) (except top row 16 - 1)
|
||||
//When layer 1 is active, key LEDs use red (id1 64 - 33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
|
||||
//When layer 1 is active, key LEDs use red (id2 87 - 65: 0000 0000 0111 1111 1111 1111 1111 1111 = 0x007FFFFF)
|
||||
//When layer 1 is active, edge LEDs use green (id2 95 - 88: 1111 1111 1000 0000 0000 0000 0000 0000 = 0xFF800000)
|
||||
//When layer 1 is active, edge LEDs use green (id3 119 - 96: 0000 0000 1111 1111 1111 1111 1111 1111 = 0x00FFFFFF)
|
||||
// { .flags = LED_FLAG_USE_ROTATE_PATTERN },
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_RGB, .id0 = 0xFFFF0000, .id1 = 0xFFFFFFFF, .id2 = 0x007FFFFF, .r = 255, .layer = 1 },
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_RGB, .id2 = 0xFF800000, .id3 = 0x00FFFFFF, .g = 127, .layer = 1 },
|
||||
|
||||
//All key LEDs use red while edge LEDs use the active pattern
|
||||
//All key LEDs use red (id0 32 - 1: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
|
||||
//All key LEDs use red (id1 64 - 33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
|
||||
//All key LEDs use red (id2 87 - 65: 0000 0000 0111 1111 1111 1111 1111 1111 = 0x007FFFFF)
|
||||
//Edge uses active pattern (id2 95 - 88: 1111 1111 1000 0000 0000 0000 0000 0000 = 0xFF800000)
|
||||
//Edge uses active pattern (id3 119 - 96: 0000 0000 1111 1111 1111 1111 1111 1111 = 0x00FFFFFF)
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFFFFFFFF, .id1 = 0xFFFFFFFF, .id2 = 0x007FFFFF, .r = 255 },
|
||||
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN , .id2 = 0xFF800000, .id3 = 0x00FFFFFF },
|
||||
|
||||
//end must be set to 1 to indicate end of instruction set
|
||||
{ .end = 1 }
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
# This keymap requires Massdrop Configurator support
|
||||
OPT_DEFS += -DUSE_MASSDROP_CONFIGURATOR
|
@ -0,0 +1,196 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
enum ctrl_keycodes {
|
||||
L_BRI = SAFE_RANGE, //LED Brightness Increase //Working
|
||||
L_BRD, //LED Brightness Decrease //Working
|
||||
L_PTN, //LED Pattern Select Next //Working
|
||||
L_PTP, //LED Pattern Select Previous //Working
|
||||
L_PSI, //LED Pattern Speed Increase //Working
|
||||
L_PSD, //LED Pattern Speed Decrease //Working
|
||||
L_T_MD, //LED Toggle Mode //Working
|
||||
L_T_ONF, //LED Toggle On / Off //Broken
|
||||
L_ON, //LED On //Broken
|
||||
L_OFF, //LED Off //Broken
|
||||
L_T_BR, //LED Toggle Breath Effect //Working
|
||||
L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working
|
||||
U_T_AGCR, //USB Toggle Automatic GCR control //Working
|
||||
DBG_TOG, //DEBUG Toggle On / Off //
|
||||
DBG_MTRX, //DEBUG Toggle Matrix Prints //
|
||||
DBG_KBD, //DEBUG Toggle Keyboard Prints //
|
||||
DBG_MOU, //DEBUG Toggle Mouse Prints //
|
||||
MD_BOOT //Restart into bootloader after hold timeout //Working
|
||||
};
|
||||
|
||||
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
|
||||
|
||||
keymap_config_t keymap_config;
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = 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_PSCR, KC_SLCK, KC_PAUS, \
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
|
||||
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
|
||||
),
|
||||
[1] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \
|
||||
L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \
|
||||
L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
/*
|
||||
[X] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
|
||||
),
|
||||
*/
|
||||
};
|
||||
|
||||
// Runs just one time when the keyboard initializes.
|
||||
void matrix_init_user(void) {
|
||||
};
|
||||
|
||||
// Runs constantly in the background, in a loop.
|
||||
void matrix_scan_user(void) {
|
||||
};
|
||||
|
||||
#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
|
||||
#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
|
||||
#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
static uint32_t key_timer;
|
||||
|
||||
switch (keycode) {
|
||||
case L_BRI:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX;
|
||||
else gcr_desired += LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_BRD:
|
||||
if (record->event.pressed) {
|
||||
if (LED_GCR_STEP > gcr_desired) gcr_desired = 0;
|
||||
else gcr_desired -= LED_GCR_STEP;
|
||||
if (led_animation_breathing) gcr_breathe = gcr_desired;
|
||||
}
|
||||
return false;
|
||||
case L_PTN:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == led_setups_count - 1) led_animation_id = 0;
|
||||
else led_animation_id++;
|
||||
}
|
||||
return false;
|
||||
case L_PTP:
|
||||
if (record->event.pressed) {
|
||||
if (led_animation_id == 0) led_animation_id = led_setups_count - 1;
|
||||
else led_animation_id--;
|
||||
}
|
||||
return false;
|
||||
case L_PSI:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed += ANIMATION_SPEED_STEP;
|
||||
}
|
||||
return false;
|
||||
case L_PSD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_speed -= ANIMATION_SPEED_STEP;
|
||||
if (led_animation_speed < 0) led_animation_speed = 0;
|
||||
}
|
||||
return false;
|
||||
case L_T_MD:
|
||||
if (record->event.pressed) {
|
||||
led_lighting_mode++;
|
||||
if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
case L_T_ONF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = !led_enabled;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_ON:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 1;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_OFF:
|
||||
if (record->event.pressed) {
|
||||
led_enabled = 0;
|
||||
I2C3733_Control_Set(led_enabled);
|
||||
}
|
||||
return false;
|
||||
case L_T_BR:
|
||||
if (record->event.pressed) {
|
||||
led_animation_breathing = !led_animation_breathing;
|
||||
if (led_animation_breathing) {
|
||||
gcr_breathe = gcr_desired;
|
||||
led_animation_breathe_cur = BREATHE_MIN_STEP;
|
||||
breathe_dir = 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case L_T_PTD:
|
||||
if (record->event.pressed) {
|
||||
led_animation_direction = !led_animation_direction;
|
||||
}
|
||||
return false;
|
||||
case U_T_AGCR:
|
||||
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
|
||||
TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_TOG:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
|
||||
}
|
||||
return false;
|
||||
case DBG_MTRX:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
|
||||
}
|
||||
return false;
|
||||
case DBG_KBD:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
|
||||
}
|
||||
return false;
|
||||
case DBG_MOU:
|
||||
if (record->event.pressed) {
|
||||
TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
|
||||
}
|
||||
return false;
|
||||
case MD_BOOT:
|
||||
if (record->event.pressed) {
|
||||
key_timer = timer_read32();
|
||||
} else {
|
||||
if (timer_elapsed32(key_timer) >= 500) {
|
||||
reset_keyboard();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return true; //Process all other keycodes normally
|
||||
}
|
||||
}
|
||||
|
||||
led_instruction_t led_instructions[] = {
|
||||
//Please see ../default_md/keymap.c for examples
|
||||
|
||||
//All LEDs use the user's selected pattern (this is the factory default)
|
||||
{ .flags = LED_FLAG_USE_ROTATE_PATTERN },
|
||||
|
||||
//end must be set to 1 to indicate end of instruction set
|
||||
{ .end = 1 }
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
# This keymap requires Massdrop Configurator support
|
||||
OPT_DEFS += -DUSE_MASSDROP_CONFIGURATOR
|
@ -0,0 +1,5 @@
|
||||
# THIS KEYMAP IS BROKEN
|
||||
|
||||
The CTRL and ALT have both been switched to using the QMK RGB Matrix system,
|
||||
rendering any custom effects that used the old, custom Massdrop lighting system,
|
||||
BROKEN.
|
@ -0,0 +1,2 @@
|
||||
# This keymap requires Massdrop Configurator support
|
||||
OPT_DEFS += -DUSE_MASSDROP_CONFIGURATOR
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
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 "ctrl.h"
|
||||
#include "led_matrix.h"
|
||||
|
||||
//Teal <-> Salmon
|
||||
led_setup_t leds_teal_salmon[] = {
|
||||
{ .hs = 0, .he = 33, .rs = 24, .re = 24, .gs = 215, .ge = 215, .bs = 204, .be = 204, .ef = EF_NONE },
|
||||
{ .hs = 33, .he = 66, .rs = 24, .re = 255, .gs = 215, .ge = 114, .bs = 204, .be = 118, .ef = EF_NONE },
|
||||
{ .hs = 66, .he = 100, .rs = 255, .re = 255, .gs = 114, .ge = 114, .bs = 118, .be = 118, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Yellow
|
||||
led_setup_t leds_yellow[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Off
|
||||
led_setup_t leds_off[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Red
|
||||
led_setup_t leds_red[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Green
|
||||
led_setup_t leds_green[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Blue
|
||||
led_setup_t leds_blue[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//White
|
||||
led_setup_t leds_white[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//White with moving red stripe
|
||||
led_setup_t leds_white_with_red_stripe[] = {
|
||||
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE },
|
||||
{ .hs = 0, .he = 15, .rs = 0, .re = 0, .gs = 0, .ge = 255, .bs = 0, .be = 255, .ef = EF_SCR_R | EF_SUBTRACT },
|
||||
{ .hs = 15, .he = 30, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 0, .ef = EF_SCR_R | EF_SUBTRACT },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Black with moving red stripe
|
||||
led_setup_t leds_black_with_red_stripe[] = {
|
||||
{ .hs = 0, .he = 15, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R },
|
||||
{ .hs = 15, .he = 30, .rs = 255, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Rainbow no scrolling
|
||||
led_setup_t leds_rainbow_ns[] = {
|
||||
{ .hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER },
|
||||
{ .hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER },
|
||||
{ .hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER },
|
||||
{ .hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER },
|
||||
{ .hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER },
|
||||
{ .hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Rainbow scrolling
|
||||
led_setup_t leds_rainbow_s[] = {
|
||||
{ .hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R },
|
||||
{ .hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R },
|
||||
{ .hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER | EF_SCR_R },
|
||||
{ .hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R },
|
||||
{ .hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R },
|
||||
{ .hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER | EF_SCR_R },
|
||||
{ .end = 1 },
|
||||
};
|
||||
|
||||
//Add new LED animations here using one from above as example
|
||||
//The last entry must be { .end = 1 }
|
||||
//Add the new animation name to the list below following its format
|
||||
|
||||
void *led_setups[] = {
|
||||
leds_rainbow_s,
|
||||
leds_rainbow_ns,
|
||||
leds_teal_salmon,
|
||||
leds_yellow,
|
||||
leds_red,
|
||||
leds_green,
|
||||
leds_blue,
|
||||
leds_white,
|
||||
leds_white_with_red_stripe,
|
||||
leds_black_with_red_stripe,
|
||||
leds_off
|
||||
};
|
||||
|
||||
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);
|
@ -1,8 +1,6 @@
|
||||
#ifndef CONFIG_USER_H
|
||||
#pragma once
|
||||
|
||||
#define CONFIG_USER_H
|
||||
#define TAPPING_TERM 200
|
||||
#include "../../config.h"
|
||||
#define PERMISSIVE_HOLD
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
TAP_DANCE_ENABLE = yes
|
||||
MOUSEKEY_ENABLE = yes
|
||||
|
||||
|
||||
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
Copyright 2019 mechmerlin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x0000
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER Quantrik
|
||||
#define PRODUCT Kyuu
|
||||
#define DESCRIPTION A 65% keyboard with blocker
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 5
|
||||
#define MATRIX_COLS 15
|
||||
|
||||
/*
|
||||
* Keyboard Matrix Assignments
|
||||
*
|
||||
* Change this to how you wired your keyboard
|
||||
* COLS: AVR pins used for columns, left to right
|
||||
* ROWS: AVR pins used for rows, top to bottom
|
||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||
*
|
||||
*/
|
||||
#define MATRIX_ROW_PINS { B6, B5, B4, D7, D6 }
|
||||
#define MATRIX_COL_PINS { F1, F4, F5, F6, F7, C7, C6, F0, B7, D0, D5, D3, D2, D1, B3 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW, ROW2COL*/
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/*
|
||||
* Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
|
||||
*/
|
||||
// #define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
|
||||
|
||||
// #define BACKLIGHT_PIN B7
|
||||
// #define BACKLIGHT_BREATHING
|
||||
// #define BACKLIGHT_LEVELS 3
|
||||
|
||||
// #define RGB_DI_PIN E2
|
||||
// #ifdef RGB_DI_PIN
|
||||
// #define RGBLED_NUM 16
|
||||
// #define RGBLIGHT_HUE_STEP 8
|
||||
// #define RGBLIGHT_SAT_STEP 8
|
||||
// #define RGBLIGHT_VAL_STEP 8
|
||||
// #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
|
||||
// #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
|
||||
// /*== all animations enable ==*/
|
||||
// #define RGBLIGHT_ANIMATIONS
|
||||
// /*== or choose animations ==*/
|
||||
// #define RGBLIGHT_EFFECT_BREATHING
|
||||
// #define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
// #define RGBLIGHT_EFFECT_SNAKE
|
||||
// #define RGBLIGHT_EFFECT_KNIGHT
|
||||
// #define RGBLIGHT_EFFECT_CHRISTMAS
|
||||
// #define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
// #define RGBLIGHT_EFFECT_RGB_TEST
|
||||
// #define RGBLIGHT_EFFECT_ALTERNATING
|
||||
// #endif
|
||||
|
||||
/* 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
|
||||
|
||||
/* number of backlight levels */
|
||||
|
||||
/* 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
|
||||
|
||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
|
||||
* This is userful for the Windows task manager shortcut (ctrl+shift+esc).
|
||||
*/
|
||||
// #define GRAVE_ESC_CTRL_OVERRIDE
|
||||
|
||||
/*
|
||||
* Force NKRO
|
||||
*
|
||||
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
|
||||
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
|
||||
* makefile for this to work.)
|
||||
*
|
||||
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
|
||||
* until the next keyboard reset.
|
||||
*
|
||||
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
|
||||
* fully operational during normal computer usage.
|
||||
*
|
||||
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
|
||||
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
|
||||
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
|
||||
* power-up.
|
||||
*
|
||||
*/
|
||||
//#define FORCE_NKRO
|
||||
|
||||
/*
|
||||
* Magic Key Options
|
||||
*
|
||||
* Magic keys are hotkey commands that allow control over firmware functions of
|
||||
* the keyboard. They are best used in combination with the HID Listen program,
|
||||
* found here: https://www.pjrc.com/teensy/hid_listen.html
|
||||
*
|
||||
* The options below allow the magic key functionality to be changed. This is
|
||||
* useful if your keyboard/keypad is missing keys and you want magic key support.
|
||||
*
|
||||
*/
|
||||
|
||||
/* key combination for magic key command */
|
||||
/* defined by default; to change, uncomment and set to the combination you want */
|
||||
// #define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
|
||||
|
||||
/* control how magic key switches layers */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
|
||||
|
||||
/* override magic key keymap */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
//#define MAGIC_KEY_HELP H
|
||||
//#define MAGIC_KEY_HELP_ALT SLASH
|
||||
//#define MAGIC_KEY_DEBUG D
|
||||
//#define MAGIC_KEY_DEBUG_MATRIX X
|
||||
//#define MAGIC_KEY_DEBUG_KBD K
|
||||
//#define MAGIC_KEY_DEBUG_MOUSE M
|
||||
//#define MAGIC_KEY_VERSION V
|
||||
//#define MAGIC_KEY_STATUS S
|
||||
//#define MAGIC_KEY_CONSOLE C
|
||||
//#define MAGIC_KEY_LAYER0 0
|
||||
//#define MAGIC_KEY_LAYER0_ALT GRAVE
|
||||
//#define MAGIC_KEY_LAYER1 1
|
||||
//#define MAGIC_KEY_LAYER2 2
|
||||
//#define MAGIC_KEY_LAYER3 3
|
||||
//#define MAGIC_KEY_LAYER4 4
|
||||
//#define MAGIC_KEY_LAYER5 5
|
||||
//#define MAGIC_KEY_LAYER6 6
|
||||
//#define MAGIC_KEY_LAYER7 7
|
||||
//#define MAGIC_KEY_LAYER8 8
|
||||
//#define MAGIC_KEY_LAYER9 9
|
||||
//#define MAGIC_KEY_BOOTLOADER B
|
||||
//#define MAGIC_KEY_BOOTLOADER_ALT ESC
|
||||
//#define MAGIC_KEY_LOCK CAPS
|
||||
//#define MAGIC_KEY_EEPROM E
|
||||
//#define MAGIC_KEY_EEPROM_CLEAR BSPACE
|
||||
//#define MAGIC_KEY_NKRO N
|
||||
//#define MAGIC_KEY_SLEEP_LED Z
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
//#define MIDI_BASIC
|
||||
|
||||
/* enable advanced MIDI features:
|
||||
- MIDI notes can be added to the keymap
|
||||
- Octave shift and transpose
|
||||
- Virtual sustain, portamento, and modulation wheel
|
||||
- etc.
|
||||
*/
|
||||
//#define MIDI_ADVANCED
|
||||
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 1
|
||||
|
||||
/*
|
||||
* HD44780 LCD Display Configuration
|
||||
*/
|
||||
/*
|
||||
#define LCD_LINES 2 //< number of visible lines of the display
|
||||
#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display
|
||||
|
||||
#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode
|
||||
|
||||
#if LCD_IO_MODE
|
||||
#define LCD_PORT PORTB //< port for the LCD lines
|
||||
#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0
|
||||
#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1
|
||||
#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2
|
||||
#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3
|
||||
#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0
|
||||
#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1
|
||||
#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2
|
||||
#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3
|
||||
#define LCD_RS_PORT LCD_PORT //< port for RS line
|
||||
#define LCD_RS_PIN 3 //< pin for RS line
|
||||
#define LCD_RW_PORT LCD_PORT //< port for RW line
|
||||
#define LCD_RW_PIN 2 //< pin for RW line
|
||||
#define LCD_E_PORT LCD_PORT //< port for Enable line
|
||||
#define LCD_E_PIN 1 //< pin for Enable line
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Bootmagic Lite key configuration */
|
||||
// #define BOOTMAGIC_LITE_ROW 0
|
||||
// #define BOOTMAGIC_LITE_COLUMN 0
|
@ -0,0 +1,82 @@
|
||||
{
|
||||
"keyboard_name": "Kyuu",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"width": 16,
|
||||
"height": 5,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"key_count": 67,
|
||||
"layout": [
|
||||
{"label":"K00 (B6,F1)", "x":0, "y":0},
|
||||
{"label":"K01 (B6,F4)", "x":1, "y":0},
|
||||
{"label":"K02 (B6,F5)", "x":2, "y":0},
|
||||
{"label":"K03 (B6,F6)", "x":3, "y":0},
|
||||
{"label":"K04 (B6,F7)", "x":4, "y":0},
|
||||
{"label":"K05 (B6,C7)", "x":5, "y":0},
|
||||
{"label":"K06 (B6,C6)", "x":6, "y":0},
|
||||
{"label":"K07 (B6,F0)", "x":7, "y":0},
|
||||
{"label":"K08 (B6,B7)", "x":8, "y":0},
|
||||
{"label":"K09 (B6,D0)", "x":9, "y":0},
|
||||
{"label":"K0A (B6,D5)", "x":10, "y":0},
|
||||
{"label":"K0B (B6,D3)", "x":11, "y":0},
|
||||
{"label":"K0C (B6,D2)", "x":12, "y":0},
|
||||
{"label":"K0D (B6,D1)", "x":13, "y":0},
|
||||
{"label":"K0E (B6,B3)", "x":14, "y":0},
|
||||
{"label":"K2E (B4,B3)", "x":15, "y":0},
|
||||
{"label":"K10 (B5,F1)", "x":0, "y":1, "w":1.5},
|
||||
{"label":"K11 (B5,F4)", "x":1.5, "y":1},
|
||||
{"label":"K12 (B5,F5)", "x":2.5, "y":1},
|
||||
{"label":"K13 (B5,F6)", "x":3.5, "y":1},
|
||||
{"label":"K14 (B5,F7)", "x":4.5, "y":1},
|
||||
{"label":"K15 (B5,C7)", "x":5.5, "y":1},
|
||||
{"label":"K16 (B5,C6)", "x":6.5, "y":1},
|
||||
{"label":"K17 (B5,F0)", "x":7.5, "y":1},
|
||||
{"label":"K18 (B5,B7)", "x":8.5, "y":1},
|
||||
{"label":"K19 (B5,D0)", "x":9.5, "y":1},
|
||||
{"label":"K1A (B5,D5)", "x":10.5, "y":1},
|
||||
{"label":"K1B (B5,D3)", "x":11.5, "y":1},
|
||||
{"label":"K1C (B5,D2)", "x":12.5, "y":1},
|
||||
{"label":"K1D (B5,D1)", "x":13.5, "y":1, "w":1.5},
|
||||
{"label":"K1E (B5,B3)", "x":15, "y":1},
|
||||
{"label":"K20 (B4,F1)", "x":0, "y":2, "w":1.75},
|
||||
{"label":"K21 (B4,F4)", "x":1.75, "y":2},
|
||||
{"label":"K22 (B4,F5)", "x":2.75, "y":2},
|
||||
{"label":"K23 (B4,F6)", "x":3.75, "y":2},
|
||||
{"label":"K24 (B4,F7)", "x":4.75, "y":2},
|
||||
{"label":"K25 (B4,C7)", "x":5.75, "y":2},
|
||||
{"label":"K26 (B4,C6)", "x":6.75, "y":2},
|
||||
{"label":"K27 (B4,F0)", "x":7.75, "y":2},
|
||||
{"label":"K28 (B4,B7)", "x":8.75, "y":2},
|
||||
{"label":"K29 (B4,D0)", "x":9.75, "y":2},
|
||||
{"label":"K2A (B4,D5)", "x":10.75, "y":2},
|
||||
{"label":"K2B (B4,D3)", "x":11.75, "y":2},
|
||||
{"label":"K2C (B4,D2)", "x":12.75, "y":2, "w":2.25},
|
||||
{"label":"K2D (B4,D1)", "x":15, "y":2},
|
||||
{"label":"K30 (D7,F1)", "x":0, "y":3, "w":2.25},
|
||||
{"label":"K31 (D7,F4)", "x":2.25, "y":3},
|
||||
{"label":"K32 (D7,F5)", "x":3.25, "y":3},
|
||||
{"label":"K33 (D7,F6)", "x":4.25, "y":3},
|
||||
{"label":"K34 (D7,F7)", "x":5.25, "y":3},
|
||||
{"label":"K35 (D7,C7)", "x":6.25, "y":3},
|
||||
{"label":"K36 (D7,C6)", "x":7.25, "y":3},
|
||||
{"label":"K37 (D7,F0)", "x":8.25, "y":3},
|
||||
{"label":"K38 (D7,B7)", "x":9.25, "y":3},
|
||||
{"label":"K39 (D7,D0)", "x":10.25, "y":3},
|
||||
{"label":"K3A (D7,D5)", "x":11.25, "y":3},
|
||||
{"label":"K3B (D7,D3)", "x":12.25, "y":3, "w":1.75},
|
||||
{"label":"K3C (D7,D2)", "x":14, "y":3},
|
||||
{"label":"K3D (D7,D1)", "x":15, "y":3},
|
||||
{"label":"K40 (D6,F1)", "x":0, "y":4, "w":1.5},
|
||||
{"label":"K41 (D6,F4)", "x":1.5, "y":4},
|
||||
{"label":"K42 (D6,F5)", "x":2.5, "y":4, "w":1.5},
|
||||
{"label":"K46 (D6,C6)", "x":4, "y":4, "w":7},
|
||||
{"label":"K4A (D6,D5)", "x":11, "y":4, "w":1.5},
|
||||
{"label":"K4B (D6,D3)", "x":13, "y":4},
|
||||
{"label":"K4C (D6,D2)", "x":14, "y":4},
|
||||
{"label":"K4D (D6,D1)", "x":15, "y":4}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
/* Copyright 2019 mechmerlin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
@ -0,0 +1,74 @@
|
||||
/* Copyright 2019 mechmerlin
|
||||
*
|
||||
* 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
|
||||
|
||||
// Defines the keycodes used by our macros in process_record_user
|
||||
enum custom_keycodes {
|
||||
QMKBEST = SAFE_RANGE,
|
||||
QMKURL
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT( \
|
||||
KC_ESC, 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_BSLS, KC_GRV, KC_HOME, \
|
||||
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_BSPC, KC_PGUP, \
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_UP, KC_END, \
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_RGHT \
|
||||
),
|
||||
[1] = LAYOUT( \
|
||||
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, QMKBEST, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 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, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
|
||||
),
|
||||
|
||||
};
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case QMKBEST:
|
||||
if (record->event.pressed) {
|
||||
// when keycode QMKBEST is pressed
|
||||
SEND_STRING("QMK is the best thing ever!");
|
||||
} else {
|
||||
// when keycode QMKBEST is released
|
||||
}
|
||||
break;
|
||||
case QMKURL:
|
||||
if (record->event.pressed) {
|
||||
// when keycode QMKURL is pressed
|
||||
SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER));
|
||||
} else {
|
||||
// when keycode QMKURL is released
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void matrix_init_user(void) {
|
||||
|
||||
}
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
|
||||
}
|
||||
|
||||
void led_set_user(uint8_t usb_led) {
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
# The default keymap for Kyuu
|
@ -0,0 +1,43 @@
|
||||
/* Copyright 2019 mechmerlin
|
||||
*
|
||||
* 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 "kyuu.h"
|
||||
|
||||
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
|
||||
|
||||
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,42 @@
|
||||
/* Copyright 2019 mechmerlin
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
/* This a shortcut to help you visually see your layout.
|
||||
*
|
||||
* The first section contains all of the arguments representing the physical
|
||||
* layout of the board and position of the keys.
|
||||
*
|
||||
* The second converts the arguments into a two-dimensional array which
|
||||
* represents the switch matrix.
|
||||
*/
|
||||
#define LAYOUT( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k2E, \
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, \
|
||||
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, \
|
||||
k40, k41, k42, k46, k47, k4A, k4B, k4C, k4D \
|
||||
) \
|
||||
{ \
|
||||
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E }, \
|
||||
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E }, \
|
||||
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, KC_NO, k2E }, \
|
||||
{ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, KC_NO }, \
|
||||
{ k40, k41, k42, KC_NO, KC_NO, KC_NO, k46, k47, KC_NO, KC_NO, k4A, k4B, k4C, k4D, KC_NO }, \
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
# kyuu
|
||||
|
||||
Kyuu is a 65% keyboard inspired by the TGR 910's top right blocker.
|
||||
|
||||
Keyboard Maintainer: [MechMerlin](https://github.com/mechmerlin)
|
||||
Hardware Supported: Quantrik 65% PCB
|
||||
Hardware Availability: [Geekhack Group Buy](https://geekhack.org/index.php?topic=97810.0), [quantrik.com](https://www.quantrik.com/collections/frontpage/products/kyuu-keyboard)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make quantrik/kyuu:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
@ -0,0 +1,81 @@
|
||||
# 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 selection
|
||||
# Teensy halfkay
|
||||
# Pro Micro caterina
|
||||
# Atmel DFU atmel-dfu
|
||||
# LUFA DFU lufa-dfu
|
||||
# QMK DFU qmk-dfu
|
||||
# atmega32a bootloadHID
|
||||
BOOTLOADER = atmel-dfu
|
||||
|
||||
|
||||
# If you don't know the bootloader type, then you can specify the
|
||||
# Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
# OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = yes # Console for debug(+400)
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
# 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 = no # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
|
||||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||
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
|
||||
HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400)
|
@ -0,0 +1,127 @@
|
||||
/* Copyright 2017 Jason Williams (Wilba)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
// USB Device descriptor parameter
|
||||
#define VENDOR_ID 0x5241 // "RW"
|
||||
#define PRODUCT_ID 0x4B59 // "KY"
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER RAMA.WORKS
|
||||
#define PRODUCT RAMA KOYU
|
||||
#define DESCRIPTION RAMA KOYU Keyboard
|
||||
|
||||
|
||||
|
||||
// key matrix size
|
||||
#define MATRIX_ROWS 5
|
||||
#define MATRIX_COLS 15
|
||||
|
||||
// KOYU PCB pin-out
|
||||
#define MATRIX_ROW_PINS { F0, F1, F4, F6, F7 }
|
||||
#define MATRIX_COL_PINS { F5, D5, B1, B2, B3, D3, D2, C7, C6, B6, B5, B4, D7, D6, D4 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
// IS31FL3731 driver
|
||||
#define DRIVER_COUNT 2
|
||||
#define DRIVER_LED_TOTAL 72
|
||||
|
||||
// COL2ROW or ROW2COL
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
#define RGB_BACKLIGHT_ENABLED 1
|
||||
|
||||
// This conditionally compiles the backlight code for KOYU specifics
|
||||
#define RGB_BACKLIGHT_KOYU
|
||||
|
||||
// enable/disable LEDs based on layout
|
||||
// they aren't really used if RGB_BACKLIGHT_M60_A defined
|
||||
#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 1
|
||||
#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
|
||||
#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 1
|
||||
#define RGB_BACKLIGHT_USE_7U_SPACEBAR 1
|
||||
#define RGB_BACKLIGHT_USE_ISO_ENTER 0
|
||||
#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 1
|
||||
|
||||
// disable backlight when USB suspended (PC sleep/hibernate/shutdown)
|
||||
#define RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED 0
|
||||
|
||||
// disable backlight after timeout in minutes, 0 = no timeout
|
||||
#define RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT 0
|
||||
|
||||
// the default effect (RGB test)
|
||||
#define RGB_BACKLIGHT_EFFECT 255
|
||||
|
||||
// These define which keys in the matrix are alphas/mods
|
||||
// Used for backlight effects so colors are different for
|
||||
// alphas vs. mods
|
||||
// Each value is for a row, bit 0 is column 0
|
||||
// Alpha=0 Mod=1
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0110000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0110000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0111000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0111000000000001
|
||||
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0111100000000111
|
||||
|
||||
#define DYNAMIC_KEYMAP_LAYER_COUNT 4
|
||||
|
||||
// EEPROM usage
|
||||
|
||||
// TODO: refactor with new user EEPROM code (coming soon)
|
||||
#define EEPROM_MAGIC 0x451F
|
||||
#define EEPROM_MAGIC_ADDR 32
|
||||
// Bump this every time we change what we store
|
||||
// This will automatically reset the EEPROM with defaults
|
||||
// and avoid loading invalid data from the EEPROM
|
||||
#define EEPROM_VERSION 0x08
|
||||
#define EEPROM_VERSION_ADDR 34
|
||||
|
||||
// Backlight config starts after EEPROM version
|
||||
#define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR 35
|
||||
// Dynamic keymap starts after backlight config (35+31)
|
||||
#define DYNAMIC_KEYMAP_EEPROM_ADDR 66
|
||||
// Dynamic macro starts after dynamic keymaps (66+(4*5*15*2)) = (66+600)
|
||||
#define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 666
|
||||
#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 358
|
||||
#define DYNAMIC_KEYMAP_MACRO_COUNT 16
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"keyboard_name": "KOYU",
|
||||
"url": "",
|
||||
"maintainer": "Wilba",
|
||||
"bootloader": "DFU",
|
||||
"width": 16,
|
||||
"height": 5,
|
||||
"layouts": {
|
||||
"LAYOUT_all": {
|
||||
"layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"PrtSc", "x":13, "y":0}, {"label":"Pause", "x":14, "y":0}, {"label":"Num Lock", "x":15, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Insert", "x":15, "y":1}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Home", "x":15, "y":2}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"\u2191", "x":14, "y":3}, {"label":"/", "x":15, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.5}, {"label":"Win", "x":1.5, "y":4}, {"label":"Alt", "x":2.5, "y":4, "w":1.5}, {"x":4, "y":4, "w":7}, {"label":"Ctrl", "x":11, "y":4, "w":1.5}, {"label":"\u2190", "x":13, "y":4}, {"label":"\u2193", "x":14, "y":4}, {"label":"\u2192", "x":15, "y":4}]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
// Default layer
|
||||
[0] = LAYOUT_all(
|
||||
KC_ESC, 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_BSLS, KC_DEL, KC_HOME,
|
||||
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_BSPC, KC_PGUP,
|
||||
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END,
|
||||
MO(1), KC_LGUI, KC_LALT, KC_SPC, MO(2), KC_LEFT, KC_DOWN, KC_RGHT),
|
||||
|
||||
// Fn1 Layer
|
||||
[1] = LAYOUT_all(
|
||||
KC_GRV, 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_INS, KC_DEL, KC_TRNS,
|
||||
KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_EJCT, 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),
|
||||
|
||||
// Fn2 Layer
|
||||
[2] = LAYOUT_all(
|
||||
KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, 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_TRNS, KC_TRNS, KC_TRNS),
|
||||
|
||||
// Fn3 Layer
|
||||
[3] = LAYOUT_all(
|
||||
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_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),
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
*
|
||||
* 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 RGB_BACKLIGHT_KOYU
|
||||
#error RGB_BACKLIGHT_KOYU not defined, you done goofed somehao, brah
|
||||
#endif
|
@ -0,0 +1,42 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
#include "../../zeal60/rgb_backlight_keycodes.h"
|
||||
#include "../../zeal60/zeal60_keycodes.h"
|
||||
|
||||
#define ____ KC_NO
|
||||
|
||||
// Right switch of split backspace is at 2,13 and is the only switch
|
||||
// whose physical position doesn't match switch matrix position :-(
|
||||
// However, it also makes no sense to view the physical as 16 columns,
|
||||
// so the numbering goes 00 to 14. Deal with it.
|
||||
|
||||
#define LAYOUT_all( \
|
||||
K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K213, K014, \
|
||||
K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, \
|
||||
K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K214, \
|
||||
K300, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K313, K314, \
|
||||
K400, K401, K402, K407, K411, K412, K413, K414 \
|
||||
) { \
|
||||
{ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 }, \
|
||||
{ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 }, \
|
||||
{ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214 }, \
|
||||
{ K300, ____, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K313, K314 }, \
|
||||
{ K400, K401, K402, ____, ____, ____, ____, K407, ____, ____, ____, K411, K412, K413, K414 } \
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
|
||||
|
||||
# project specific files
|
||||
SRC = keyboards/zeal60/zeal60.c \
|
||||
keyboards/zeal60/rgb_backlight.c \
|
||||
quantum/color.c \
|
||||
drivers/issi/is31fl3731.c \
|
||||
drivers/avr/i2c_master.c
|
||||
|
||||
# MCU name
|
||||
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
|
||||
|
||||
# Boot Section
|
||||
BOOTLOADER = atmel-dfu
|
||||
|
||||
# Do not put the microcontroller into power saving mode
|
||||
# when we get USB suspend event. We want it to keep updating
|
||||
# backlight effects.
|
||||
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
|
||||
|
||||
# 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 = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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 = no # Unicode
|
||||
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight.
|
||||
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
|
||||
RAW_ENABLE = yes
|
||||
DYNAMIC_KEYMAP_ENABLE = yes
|
||||
CIE1931_CURVE = yes
|
||||
|
||||
#LAYOUTS = ???
|
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6060
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER TheRoyalSweatshirt
|
||||
#define PRODUCT romac
|
||||
#define DESCRIPTION A *Plaid inspired twelve-key macropad
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 4
|
||||
#define MATRIX_COLS 3
|
||||
|
||||
/* key matrix pins */
|
||||
#define MATRIX_ROW_PINS { D4, C6, D7, E6 }
|
||||
#define MATRIX_COL_PINS { F7, B1, B3 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* number of backlight levels */
|
||||
|
||||
#define BACKLIGHT_LEVELS 0
|
||||
|
||||
/* 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
|
||||
|
||||
#define RGBLED_NUM 0
|
||||
#define RGBLIGHT_HUE_STEP 8
|
||||
#define RGBLIGHT_SAT_STEP 8
|
||||
#define RGBLIGHT_VAL_STEP 8
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"keyboard_name": "RoMac",
|
||||
"url": "",
|
||||
"maintainer": "TheRoyalSweatshirt",
|
||||
"width": 3,
|
||||
"height": 4,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"key_count": 12,
|
||||
"layout": [{"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/* Copyright 2018 Jack Humbert
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
#define _BASE 0
|
||||
#define _FN1 1
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_BASE] = LAYOUT(
|
||||
KC_7, KC_8, KC_9, \
|
||||
KC_4, KC_5, KC_6, \
|
||||
KC_1, KC_2, KC_3, \
|
||||
MO(_FN1), KC_0, KC_ENT \
|
||||
),
|
||||
|
||||
[_FN1] = LAYOUT(
|
||||
KC_TRNS, KC_HOME, KC_PGUP, \
|
||||
KC_TRNS, KC_END, KC_PGDN, \
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, \
|
||||
KC_TRNS, KC_TRNS, KC_DOT \
|
||||
)
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
|
||||
# RoMac
|
||||
|
||||
![RoMac](https://i.imgur.com/hAOyoqj.jpg)
|
||||
|
||||
A “Plaid” Inspired 12-Key (3x4) Macropad.
|
||||
|
||||
- Keyboard Maintainer: [Garret G.](https://github.com/TheRoyalSweatshirt)
|
||||
- Hardware Supported: RoMac rev.1, rev.2, Pro Micro, Elite-C, Proton C, BlueMicro.
|
||||
- Hardware Availability: Through GB or Direct Message (If extra stock is available).
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make romac:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
@ -0,0 +1 @@
|
||||
#include "romac.h"
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define LAYOUT( \
|
||||
K00, K01, K02, \
|
||||
K10, K11, K12, \
|
||||
K20, K21, K22, \
|
||||
K30, K31, K32 \
|
||||
) \
|
||||
{ \
|
||||
{ K00, K01, K02 }, \
|
||||
{ K10, K11, K12 }, \
|
||||
{ K20, K21, K22 }, \
|
||||
{ K30, K31, K32 } \
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
# MCU name
|
||||
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
|
||||
|
||||
|
||||
# Boot Section Size in *bytes*
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
BOOTMAGIC_ENABLE = full # 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 = no # Commands for debug and configuration
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
NKRO_ENABLE = yes # USB 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
|
||||
AUDIO_ENABLE = no
|
||||
RGBLIGHT_ENABLE = no
|
||||
|
@ -0,0 +1,244 @@
|
||||
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
|
||||
// See gfxfont.h for newer custom bitmap font info.
|
||||
|
||||
#ifndef FONT5X7_H
|
||||
#define FONT5X7_H
|
||||
|
||||
#ifdef __AVR__
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#else
|
||||
#define PROGMEM
|
||||
#endif
|
||||
|
||||
// Standard ASCII 5x7 font
|
||||
|
||||
static const unsigned char font[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
|
||||
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
|
||||
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
|
||||
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
|
||||
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
|
||||
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
|
||||
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
|
||||
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
|
||||
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
|
||||
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
|
||||
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
|
||||
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
|
||||
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
|
||||
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
|
||||
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
|
||||
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
|
||||
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
|
||||
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
|
||||
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
|
||||
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
|
||||
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
|
||||
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
|
||||
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
|
||||
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
|
||||
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
|
||||
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
|
||||
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
|
||||
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
|
||||
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
|
||||
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
|
||||
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
|
||||
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
|
||||
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
|
||||
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
|
||||
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
|
||||
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
|
||||
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
|
||||
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
|
||||
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
|
||||
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
|
||||
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
|
||||
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
|
||||
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
|
||||
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
|
||||
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
|
||||
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
|
||||
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
|
||||
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
|
||||
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
|
||||
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
|
||||
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
|
||||
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
|
||||
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
|
||||
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
|
||||
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
|
||||
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
|
||||
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
|
||||
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
|
||||
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
|
||||
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
|
||||
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
|
||||
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
|
||||
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
|
||||
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
|
||||
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
|
||||
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
|
||||
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
|
||||
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
|
||||
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
|
||||
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
|
||||
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
|
||||
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
|
||||
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
|
||||
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
|
||||
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
|
||||
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
|
||||
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
|
||||
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
|
||||
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
|
||||
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
|
||||
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
|
||||
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
|
||||
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
|
||||
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
|
||||
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
|
||||
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
|
||||
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
|
||||
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
|
||||
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
|
||||
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
|
||||
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
|
||||
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
|
||||
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
|
||||
0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
|
||||
0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
|
||||
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
|
||||
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
|
||||
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
|
||||
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
|
||||
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
|
||||
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
|
||||
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
|
||||
0x4C, 0x10, 0x10, 0x10, 0x7C, 0x00,
|
||||
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
|
||||
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
|
||||
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
|
||||
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
|
||||
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
#endif // FONT5X7_H
|
@ -0,0 +1,83 @@
|
||||
#ifdef SSD1306OLED
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "ssd1306.h"
|
||||
|
||||
void render_logo(struct CharacterMatrix *matrix) {
|
||||
|
||||
const char logo_buf[]={
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,
|
||||
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,
|
||||
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,
|
||||
0};
|
||||
|
||||
matrix_write(matrix, logo_buf);
|
||||
}
|
||||
|
||||
static char keylog_buf[24] = "Key state ready.";
|
||||
const char code_to_name[60] = {
|
||||
' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
|
||||
'R', 'E', 'B', 'T', ' ', '-', ' ', '@', ' ', ' ',
|
||||
' ', ';', ':', ' ', ',', '.', '/', ' ', ' ', ' '};
|
||||
|
||||
void update_key_status(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
if (!record->event.pressed) return;
|
||||
|
||||
char name = (keycode < 60) ? code_to_name[keycode] : ' ';
|
||||
snprintf(keylog_buf, sizeof(keylog_buf) - 1, "Key:%dx%d %2x %c",
|
||||
record->event.key.row, record->event.key.col,
|
||||
(uint16_t)keycode, name);
|
||||
}
|
||||
|
||||
void render_key_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
matrix_write(matrix, keylog_buf);
|
||||
}
|
||||
|
||||
static char lock_buf[24] = "Lock state ready.\n";
|
||||
void update_lock_status(void) {
|
||||
|
||||
uint8_t leds = host_keyboard_leds();
|
||||
char *num_lock = (leds & (1<<USB_LED_NUM_LOCK)) ? "Num" : "";
|
||||
char *caps_lock = (leds & (1<<USB_LED_CAPS_LOCK)) ? "Caps" : "";
|
||||
char *scrl_lock = (leds & (1<<USB_LED_SCROLL_LOCK)) ? "Scrn" : "";
|
||||
snprintf(lock_buf, sizeof(lock_buf) - 1, "Lock:%s %s %s\n",
|
||||
num_lock, caps_lock, scrl_lock);
|
||||
}
|
||||
|
||||
void render_lock_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
matrix_write(matrix, lock_buf);
|
||||
}
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
extern rgblight_config_t rgblight_config;
|
||||
|
||||
static char led_buf[24] = "LED state ready.\n";
|
||||
rgblight_config_t rgblight_config_bak;
|
||||
void update_led_status(void) {
|
||||
|
||||
if (rgblight_config_bak.enable != rgblight_config.enable ||
|
||||
rgblight_config_bak.mode != rgblight_config.mode ||
|
||||
rgblight_config_bak.hue != rgblight_config.hue ||
|
||||
rgblight_config_bak.sat != rgblight_config.sat ||
|
||||
rgblight_config_bak.val != rgblight_config.val
|
||||
) {
|
||||
snprintf(led_buf, sizeof(led_buf) - 1, "LED%c:%2d hsv:%2d %2d %2d\n",
|
||||
rgblight_config.enable ? '*' : '.', (uint8_t)rgblight_config.mode,
|
||||
(uint8_t)(rgblight_config.hue / RGBLIGHT_HUE_STEP),
|
||||
(uint8_t)(rgblight_config.sat / RGBLIGHT_SAT_STEP),
|
||||
(uint8_t)(rgblight_config.val / RGBLIGHT_VAL_STEP));
|
||||
rgblight_config_bak = rgblight_config;
|
||||
}
|
||||
}
|
||||
|
||||
void render_led_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
matrix_write(matrix, led_buf);
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,35 @@
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
void render_logo(struct CharacterMatrix *matrix);
|
||||
void update_key_status(uint16_t keycode, keyrecord_t *record);
|
||||
void render_key_status(struct CharacterMatrix *matrix);
|
||||
void update_lock_status(void);
|
||||
void render_lock_status(struct CharacterMatrix *matrix);
|
||||
|
||||
#define RENDER_LOGO(a) render_logo(a)
|
||||
#define UPDATE_KEY_STATUS(a, b) update_key_status(a, b)
|
||||
#define RENDER_KEY_STATUS(a) render_key_status(a)
|
||||
#define UPDATE_LOCK_STATUS() update_lock_status()
|
||||
#define RENDER_LOCK_STATUS(a) render_lock_status(a)
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
void update_led_status(void);
|
||||
void render_led_status(struct CharacterMatrix *matrix);
|
||||
#define UPDATE_LED_STATUS() update_led_status()
|
||||
#define RENDER_LED_STATUS(a) render_led_status(a)
|
||||
#else
|
||||
#define UPDATE_LED_STATUS()
|
||||
#define RENDER_LED_STATUS(a)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define RENDER_LOGO(a)
|
||||
#define UPDATE_KEY_STATUS(a, b)
|
||||
#define RENDER_KEY_STATUS(a)
|
||||
#define UPDATE_LOCK_STATUS()
|
||||
#define RENDER_LOCK_STATUS(a)
|
||||
#define UPDATE_LED_STATUS()
|
||||
#define RENDER_LED_STATUS(a)
|
||||
|
||||
#endif
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
// GCC include 'config.h" sequence in qmk_firmware/keyboards/treadstone48/
|
||||
// -include keyboards/treadstone48/config.h
|
||||
// -include keyboards/treadstone48/rev?/config.h
|
||||
// -include keyboards/treadstone48/rev?/keymaps/MAPNAME/config.h
|
||||
// XXXX.c
|
||||
|
||||
#include <serial_config.h>
|
||||
|
||||
// GCC include search path in qmk_firmare/keyboards/treadstone48/
|
||||
// #include "..." search starts here:
|
||||
// #include <...> search starts here:
|
||||
// keyboards/treadstone48/rev?/keymaps/MAPNAME
|
||||
// keyboards/treadstone48
|
||||
// keyboards/treadstone48/rev?
|
||||
// .
|
||||
// ./tmk_core
|
||||
// ......
|
||||
|
||||
// MACRO and FUNCTION are features that are depreciated.
|
||||
#define NO_ACTION_MACRO
|
||||
#define NO_ACTION_FUNCTION
|
@ -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 or 400kHz (see ./i2c.h SCL_CLOCK)
|
||||
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,46 @@
|
||||
#pragma once
|
||||
|
||||
#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 400kHz
|
||||
#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();
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
||||
|
||||
#ifdef TAPPING_TERM
|
||||
#undef TAPPING_TERM
|
||||
#endif
|
||||
#define TAPPING_TERM 225
|
||||
// #define PREVENT_STUCK_MODIFIERS
|
||||
// #define IGNORE_MOD_TAP_INTERRUPT
|
||||
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
#undef MOUSEKEY_INTERVAL
|
||||
#define MOUSEKEY_INTERVAL 1
|
||||
|
||||
#undef MOUSEKEY_TIME_TO_MAX
|
||||
#define MOUSEKEY_TIME_TO_MAX 150
|
||||
|
||||
#undef MOUSEKEY_MAX_SPEED
|
||||
#define MOUSEKEY_MAX_SPEED 3
|
||||
|
||||
#undef MOUSEKEY_MOVE_DELTA
|
||||
#define MOUSEKEY_MOVE_DELTA 4
|
||||
|
||||
#undef MOUSEKEY_DELAY
|
||||
#define MOUSEKEY_DELAY 0
|
||||
#endif
|
||||
|
||||
// Selection of RGBLIGHT MODE to use.
|
||||
#if defined(LED_ANIMATIONS)
|
||||
//#define RGBLIGHT_EFFECT_BREATHING
|
||||
#define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
#define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
//#define RGBLIGHT_EFFECT_SNAKE
|
||||
#define RGBLIGHT_EFFECT_KNIGHT
|
||||
//#define RGBLIGHT_EFFECT_CHRISTMAS
|
||||
#define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
//#define RGBLIGHT_EFFECT_RGB_TEST
|
||||
//#define RGBLIGHT_EFFECT_ALTERNATING
|
||||
#endif
|
@ -0,0 +1,278 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "keymap_jp.h"
|
||||
#include "../common/oled_helper.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
//Following line allows macro to read current RGB settings
|
||||
extern rgblight_config_t rgblight_config;
|
||||
#endif
|
||||
|
||||
extern uint8_t is_master;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
enum layer_number {
|
||||
_BASE = 0,
|
||||
_LOWER,
|
||||
_RAISE,
|
||||
_ADJUST,
|
||||
};
|
||||
|
||||
enum custom_keycodes {
|
||||
LOWER = SAFE_RANGE,
|
||||
RAISE,
|
||||
ADJUST,
|
||||
KANJI,
|
||||
RGBRST
|
||||
};
|
||||
|
||||
enum tapdances{
|
||||
TD_SCCL = 0,
|
||||
TD_SLRO,
|
||||
};
|
||||
|
||||
// Layer Mode aliases
|
||||
#define _____ KC_TRNS
|
||||
#define XXXXX KC_NO
|
||||
|
||||
#define KC_TBSF LSFT_T(KC_TAB)
|
||||
// #define KC_SPSF LSFT_T(KC_SPC)
|
||||
#define KC_ALAP LALT_T(KC_APP)
|
||||
#define KC_JEQL LSFT(KC_MINS)
|
||||
|
||||
#define KC_SCCL TD(TD_SCCL)
|
||||
#define KC_SLRO TD(TD_SLRO)
|
||||
|
||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||
[TD_SCCL] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_QUOT),
|
||||
[TD_SLRO] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_RO),
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[_BASE] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
KC_TBSF, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCCL, KC_ENT,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLRO, KC_UP, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
KC_LCTRL, KC_LALT, KC_LGUI, LOWER, KC_BSPC, KC_SPC, RAISE, KC_ALAP, KC_LEFT, KC_DOWN, KC_RGHT,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
KC_DEL \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
_____, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
_____, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, XXXXX, XXXXX, XXXXX, KC_SCLN, KC_QUOT, _____,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, KC_F11, KC_F12, XXXXX, KANJI, KC_ENT, XXXXX, XXXXX, KC_COMM, KC_DOT, KC_GRV, KC_PGUP, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, KC_DEL, _____, _____, XXXXX, KC_HOME, KC_PGDN, KC_END,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
_____, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
_____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, KC_4, KC_5, KC_6, KC_QUOT, _____,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, KC_1, KC_2, KC_3, KC_RO, XXXXX, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, _____, _____, _____, KC_0, KC_DOT, KC_COMM, KC_SLSH,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_ADJUST] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
XXXXX, RESET, RGBRST, AG_NORM, AG_SWAP, XXXXX, XXXXX, KC_WH_L, KC_WH_U, KC_HOME, KC_PGUP, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
XXXXX, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXX, XXXXX, KC_WH_R, KC_WH_D, KC_END, KC_PGDN, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXX, XXXXX, XXXXX, KC_BTN1, KC_BTN2, XXXXX, KC_MS_U, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, XXXXX, XXXXX, _____, XXXXX, KC_MS_L, KC_MS_D, KC_MS_R,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
)
|
||||
};
|
||||
|
||||
#define L_BASE _BASE
|
||||
#define L_LOWER (1<<_LOWER)
|
||||
#define L_RAISE (1<<_RAISE)
|
||||
#define L_ADJUST (1<<_ADJUST)
|
||||
#define L_ADJUST_TRI (L_ADJUST|L_RAISE|L_LOWER)
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
typedef struct {
|
||||
uint8_t state;
|
||||
char name[8];
|
||||
}LAYER_DISPLAY_NAME;
|
||||
|
||||
#define LAYER_DISPLAY_MAX 5
|
||||
const LAYER_DISPLAY_NAME layer_display_name[LAYER_DISPLAY_MAX] = {
|
||||
{L_BASE, "Base"},
|
||||
{L_BASE + 1, "Base"},
|
||||
{L_LOWER, "Lower"},
|
||||
{L_RAISE, "Raise"},
|
||||
{L_ADJUST_TRI, "Adjust"}
|
||||
};
|
||||
|
||||
static inline const char* get_leyer_status(void) {
|
||||
|
||||
for (uint8_t i = 0; i < LAYER_DISPLAY_MAX; ++i) {
|
||||
if (layer_state == 0 && layer_display_name[i].state == default_layer_state) {
|
||||
|
||||
return layer_display_name[i].name;
|
||||
} else if (layer_state != 0 && layer_display_name[i].state == layer_state) {
|
||||
|
||||
return layer_display_name[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
static char layer_status_buf[24] = "Layer state ready.\n";
|
||||
static inline void update_keymap_status(void) {
|
||||
|
||||
snprintf(layer_status_buf, sizeof(layer_status_buf) - 1, "OS:%s Layer:%s\n",
|
||||
keymap_config.swap_lalt_lgui? "win" : "mac", get_leyer_status());
|
||||
}
|
||||
|
||||
static inline void render_keymap_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
matrix_write(matrix, layer_status_buf);
|
||||
}
|
||||
|
||||
#define UPDATE_KEYMAP_STATUS() update_keymap_status()
|
||||
#define RENDER_KEYMAP_STATUS(a) render_keymap_status(a)
|
||||
|
||||
#else
|
||||
|
||||
#define UPDATE_KEYMAP_STATUS()
|
||||
#define RENDER_KEYMAP_STATUS(a)
|
||||
|
||||
#endif
|
||||
|
||||
static inline void update_change_layer(bool pressed, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||
|
||||
pressed ? layer_on(layer1) : layer_off(layer1);
|
||||
IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2) ? layer_on(layer3) : layer_off(layer3);
|
||||
}
|
||||
|
||||
int RGB_current_mode;
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
UPDATE_KEY_STATUS(keycode, record);
|
||||
|
||||
bool result = false;
|
||||
switch (keycode) {
|
||||
case LOWER:
|
||||
update_change_layer(record->event.pressed, _LOWER, _RAISE, _ADJUST);
|
||||
break;
|
||||
case RAISE:
|
||||
update_change_layer(record->event.pressed, _RAISE, _LOWER, _ADJUST);
|
||||
break;
|
||||
case KANJI:
|
||||
if (record->event.pressed) {
|
||||
if (keymap_config.swap_lalt_lgui == false) {
|
||||
register_code(KC_LANG2);
|
||||
} else {
|
||||
SEND_STRING(SS_LALT("`"));
|
||||
}
|
||||
} else {
|
||||
unregister_code(KC_LANG2);
|
||||
}
|
||||
break;
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
case RGB_MOD:
|
||||
if (record->event.pressed) {
|
||||
rgblight_mode(RGB_current_mode);
|
||||
rgblight_step();
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
}
|
||||
break;
|
||||
case RGBRST:
|
||||
if (record->event.pressed) {
|
||||
eeconfig_update_rgblight_default();
|
||||
rgblight_enable();
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
UPDATE_KEYMAP_STATUS();
|
||||
return result;
|
||||
}
|
||||
|
||||
void matrix_init_user(void) {
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
#endif
|
||||
//SSD1306 OLED init, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
iota_gfx_init(!has_usb()); // turns on the display
|
||||
#endif
|
||||
}
|
||||
|
||||
//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
iota_gfx_task(); // this is what updates the display continuously
|
||||
}
|
||||
|
||||
static inline void matrix_update(struct CharacterMatrix *dest,
|
||||
const struct CharacterMatrix *source) {
|
||||
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
|
||||
memcpy(dest->display, source->display, sizeof(dest->display));
|
||||
dest->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void render_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
UPDATE_LED_STATUS();
|
||||
RENDER_LED_STATUS(matrix);
|
||||
RENDER_KEYMAP_STATUS(matrix);
|
||||
UPDATE_LOCK_STATUS();
|
||||
RENDER_LOCK_STATUS(matrix);
|
||||
RENDER_KEY_STATUS(matrix);
|
||||
}
|
||||
|
||||
void iota_gfx_task_user(void) {
|
||||
struct CharacterMatrix matrix;
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
if (debug_enable) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
matrix_clear(&matrix);
|
||||
if (is_master) {
|
||||
render_status(&matrix);
|
||||
}
|
||||
|
||||
matrix_update(&display, &matrix);
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,5 @@
|
||||
# Default keymap for treadstone48
|
||||
|
||||
## Description
|
||||
|
||||
## How to use
|
@ -0,0 +1,67 @@
|
||||
|
||||
# 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 = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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.
|
||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing
|
||||
TAP_DANCE_ENABLE = yes
|
||||
|
||||
# If your custom treadstone48 pcb, you can rewrite to yes.
|
||||
OLED_ENABLE = no # OLED_ENABLE
|
||||
LED_UNDERGLOW_ENABLE = yes # LED underglow (Enable WS2812 RGB underlight.)
|
||||
LED_ANIMATIONS = yes # LED animations
|
||||
|
||||
# Other selectable option
|
||||
IOS_DEVICE_ENABLE = no # connect to IOS device (iPad,iPhone)
|
||||
LOCAL_GLCDFONT = no # use each keymaps "font.h" insted of "common/glcdfont.c"
|
||||
# RHYMESTONE_RIGHTHAND = no # If connect right hand side of the Rhymestone, set to yes.
|
||||
ANGELINA_KEYMAP = no # If Alfa verstion use set to yes.
|
||||
|
||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||
OPT_DEFS += -DOLED_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LED_UNDERGLOW_ENABLE)), yes)
|
||||
RGBLIGHT_ENABLE = yes
|
||||
else
|
||||
RGBLIGHT_ENABLE = no
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LED_ANIMATIONS)), yes)
|
||||
# OPT_DEFS += -DRGBLIGHT_ANIMATIONS
|
||||
OPT_DEFS += -DLED_ANIMATIONS
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(IOS_DEVICE_ENABLE)), yes)
|
||||
OPT_DEFS += -DIOS_DEVICE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LOCAL_GLCDFONT)), yes)
|
||||
OPT_DEFS += -DLOCAL_GLCDFONT
|
||||
endif
|
||||
|
||||
# ifeq ($(strip $(RHYMESTONE_RIGHTHAND)), yes)
|
||||
# OPT_DEFS += -DRHYMESTONE_RIGHTHAND
|
||||
# endif
|
||||
|
||||
ifeq ($(strip $(ANGELINA_KEYMAP)), yes)
|
||||
OPT_DEFS += -DANGELINA_KEYMAP
|
||||
endif
|
||||
|
||||
# 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 you want to change the display of OLED, you need to change here
|
||||
SRC += ./common/oled_helper.c \
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
||||
|
||||
#ifdef TAPPING_TERM
|
||||
#undef TAPPING_TERM
|
||||
#endif
|
||||
#define TAPPING_TERM 225
|
||||
// #define PREVENT_STUCK_MODIFIERS
|
||||
// #define IGNORE_MOD_TAP_INTERRUPT
|
||||
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
#undef MOUSEKEY_INTERVAL
|
||||
#define MOUSEKEY_INTERVAL 1
|
||||
|
||||
#undef MOUSEKEY_TIME_TO_MAX
|
||||
#define MOUSEKEY_TIME_TO_MAX 150
|
||||
|
||||
#undef MOUSEKEY_MAX_SPEED
|
||||
#define MOUSEKEY_MAX_SPEED 3
|
||||
|
||||
#undef MOUSEKEY_MOVE_DELTA
|
||||
#define MOUSEKEY_MOVE_DELTA 4
|
||||
|
||||
#undef MOUSEKEY_DELAY
|
||||
#define MOUSEKEY_DELAY 0
|
||||
#endif
|
||||
|
||||
// Selection of RGBLIGHT MODE to use.
|
||||
#if defined(LED_ANIMATIONS)
|
||||
//#define RGBLIGHT_EFFECT_BREATHING
|
||||
#define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
#define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
//#define RGBLIGHT_EFFECT_SNAKE
|
||||
#define RGBLIGHT_EFFECT_KNIGHT
|
||||
//#define RGBLIGHT_EFFECT_CHRISTMAS
|
||||
#define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
//#define RGBLIGHT_EFFECT_RGB_TEST
|
||||
//#define RGBLIGHT_EFFECT_ALTERNATING
|
||||
#endif
|
@ -0,0 +1,278 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "keymap_jp.h"
|
||||
#include "../common/oled_helper.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
//Following line allows macro to read current RGB settings
|
||||
extern rgblight_config_t rgblight_config;
|
||||
#endif
|
||||
|
||||
extern uint8_t is_master;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
enum layer_number {
|
||||
_BASE = 0,
|
||||
_LOWER,
|
||||
_RAISE,
|
||||
_ADJUST,
|
||||
};
|
||||
|
||||
enum custom_keycodes {
|
||||
LOWER = SAFE_RANGE,
|
||||
RAISE,
|
||||
ADJUST,
|
||||
KANJI,
|
||||
RGBRST
|
||||
};
|
||||
|
||||
enum tapdances{
|
||||
TD_SCCL = 0,
|
||||
TD_SLRO,
|
||||
};
|
||||
|
||||
// Layer Mode aliases
|
||||
#define _____ KC_TRNS
|
||||
#define XXXXX KC_NO
|
||||
|
||||
#define KC_TBSF LSFT_T(KC_TAB)
|
||||
// #define KC_SPSF LSFT_T(KC_SPC)
|
||||
#define KC_ALAP LALT_T(KC_APP)
|
||||
#define KC_JEQL LSFT(KC_MINS)
|
||||
|
||||
#define KC_SCCL TD(TD_SCCL)
|
||||
#define KC_SLRO TD(TD_SLRO)
|
||||
|
||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||
[TD_SCCL] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_QUOT),
|
||||
[TD_SLRO] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_RO),
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[_BASE] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
KC_TBSF, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCCL, KC_ENT,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLRO, KC_UP, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
KC_LCTRL, KC_LALT, KC_LGUI, LOWER, KC_BSPC, KC_SPC, RAISE, KC_ALAP, KC_LEFT, KC_DOWN, KC_RGHT,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
KC_DEL \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
_____, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MINS, KC_EQL, KC_JYEN, KC_LBRC, KC_RBRC, KC_DEL,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
_____, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, XXXXX, XXXXX, KC_SCLN, KC_QUOT, KC_BSLS, _____,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, KC_F11, KC_F12, XXXXX, KANJI, KC_ENT, XXXXX, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_PGUP, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, KC_DEL, _____, _____, XXXXX, KC_HOME, KC_PGDN, KC_END,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
_____, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
_____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, KC_4, KC_5, KC_6, KC_QUOT, _____,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, KC_1, KC_2, KC_3, KC_RO, XXXXX, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, _____, _____, _____, KC_0, KC_DOT, KC_COMM, KC_SLSH,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_ADJUST] = LAYOUT_base( \
|
||||
//,--------------------------------------------------------------------------------------------------------------------.
|
||||
XXXXX, RESET, RGBRST, AG_NORM, AG_SWAP, XXXXX, XXXXX, KC_WH_L, KC_WH_U, KC_HOME, KC_PGUP, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------|
|
||||
XXXXX, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXX, XXXXX, KC_WH_R, KC_WH_D, KC_END, KC_PGDN, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXX, XXXXX, XXXXX, KC_BTN1, KC_BTN2, XXXXX, KC_MS_U, \
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, XXXXX, XXXXX, _____, XXXXX, KC_MS_L, KC_MS_D, KC_MS_R,\
|
||||
//`-------------------------------------------------------------------------------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
)
|
||||
};
|
||||
|
||||
#define L_BASE _BASE
|
||||
#define L_LOWER (1<<_LOWER)
|
||||
#define L_RAISE (1<<_RAISE)
|
||||
#define L_ADJUST (1<<_ADJUST)
|
||||
#define L_ADJUST_TRI (L_ADJUST|L_RAISE|L_LOWER)
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
typedef struct {
|
||||
uint8_t state;
|
||||
char name[8];
|
||||
}LAYER_DISPLAY_NAME;
|
||||
|
||||
#define LAYER_DISPLAY_MAX 5
|
||||
const LAYER_DISPLAY_NAME layer_display_name[LAYER_DISPLAY_MAX] = {
|
||||
{L_BASE, "Base"},
|
||||
{L_BASE + 1, "Base"},
|
||||
{L_LOWER, "Lower"},
|
||||
{L_RAISE, "Raise"},
|
||||
{L_ADJUST_TRI, "Adjust"}
|
||||
};
|
||||
|
||||
static inline const char* get_leyer_status(void) {
|
||||
|
||||
for (uint8_t i = 0; i < LAYER_DISPLAY_MAX; ++i) {
|
||||
if (layer_state == 0 && layer_display_name[i].state == default_layer_state) {
|
||||
|
||||
return layer_display_name[i].name;
|
||||
} else if (layer_state != 0 && layer_display_name[i].state == layer_state) {
|
||||
|
||||
return layer_display_name[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
static char layer_status_buf[24] = "Layer state ready.\n";
|
||||
static inline void update_keymap_status(void) {
|
||||
|
||||
snprintf(layer_status_buf, sizeof(layer_status_buf) - 1, "OS:%s Layer:%s\n",
|
||||
keymap_config.swap_lalt_lgui? "win" : "mac", get_leyer_status());
|
||||
}
|
||||
|
||||
static inline void render_keymap_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
matrix_write(matrix, layer_status_buf);
|
||||
}
|
||||
|
||||
#define UPDATE_KEYMAP_STATUS() update_keymap_status()
|
||||
#define RENDER_KEYMAP_STATUS(a) render_keymap_status(a)
|
||||
|
||||
#else
|
||||
|
||||
#define UPDATE_KEYMAP_STATUS()
|
||||
#define RENDER_KEYMAP_STATUS(a)
|
||||
|
||||
#endif
|
||||
|
||||
static inline void update_change_layer(bool pressed, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||
|
||||
pressed ? layer_on(layer1) : layer_off(layer1);
|
||||
IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2) ? layer_on(layer3) : layer_off(layer3);
|
||||
}
|
||||
|
||||
int RGB_current_mode;
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
UPDATE_KEY_STATUS(keycode, record);
|
||||
|
||||
bool result = false;
|
||||
switch (keycode) {
|
||||
case LOWER:
|
||||
update_change_layer(record->event.pressed, _LOWER, _RAISE, _ADJUST);
|
||||
break;
|
||||
case RAISE:
|
||||
update_change_layer(record->event.pressed, _RAISE, _LOWER, _ADJUST);
|
||||
break;
|
||||
case KANJI:
|
||||
if (record->event.pressed) {
|
||||
if (keymap_config.swap_lalt_lgui == false) {
|
||||
register_code(KC_LANG2);
|
||||
} else {
|
||||
SEND_STRING(SS_LALT("`"));
|
||||
}
|
||||
} else {
|
||||
unregister_code(KC_LANG2);
|
||||
}
|
||||
break;
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
case RGB_MOD:
|
||||
if (record->event.pressed) {
|
||||
rgblight_mode(RGB_current_mode);
|
||||
rgblight_step();
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
}
|
||||
break;
|
||||
case RGBRST:
|
||||
if (record->event.pressed) {
|
||||
eeconfig_update_rgblight_default();
|
||||
rgblight_enable();
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
UPDATE_KEYMAP_STATUS();
|
||||
return result;
|
||||
}
|
||||
|
||||
void matrix_init_user(void) {
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
#endif
|
||||
//SSD1306 OLED init, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
iota_gfx_init(!has_usb()); // turns on the display
|
||||
#endif
|
||||
}
|
||||
|
||||
//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
iota_gfx_task(); // this is what updates the display continuously
|
||||
}
|
||||
|
||||
static inline void matrix_update(struct CharacterMatrix *dest,
|
||||
const struct CharacterMatrix *source) {
|
||||
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
|
||||
memcpy(dest->display, source->display, sizeof(dest->display));
|
||||
dest->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void render_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
UPDATE_LED_STATUS();
|
||||
RENDER_LED_STATUS(matrix);
|
||||
RENDER_KEYMAP_STATUS(matrix);
|
||||
UPDATE_LOCK_STATUS();
|
||||
RENDER_LOCK_STATUS(matrix);
|
||||
RENDER_KEY_STATUS(matrix);
|
||||
}
|
||||
|
||||
void iota_gfx_task_user(void) {
|
||||
struct CharacterMatrix matrix;
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
if (debug_enable) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
matrix_clear(&matrix);
|
||||
if (is_master) {
|
||||
render_status(&matrix);
|
||||
}
|
||||
|
||||
matrix_update(&display, &matrix);
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,5 @@
|
||||
# The like jis type keyboard keymap for treadstone48
|
||||
|
||||
## Description
|
||||
|
||||
## How to use
|
@ -0,0 +1,67 @@
|
||||
|
||||
# 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 = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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.
|
||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing
|
||||
TAP_DANCE_ENABLE = yes
|
||||
|
||||
# If your custom treadstone48 pcb, you can rewrite to yes.
|
||||
OLED_ENABLE = no # OLED_ENABLE
|
||||
LED_UNDERGLOW_ENABLE = yes # LED underglow (Enable WS2812 RGB underlight.)
|
||||
LED_ANIMATIONS = yes # LED animations
|
||||
|
||||
# Other selectable option
|
||||
IOS_DEVICE_ENABLE = no # connect to IOS device (iPad,iPhone)
|
||||
LOCAL_GLCDFONT = no # use each keymaps "font.h" insted of "common/glcdfont.c"
|
||||
# RHYMESTONE_RIGHTHAND = no # If connect right hand side of the Rhymestone, set to yes.
|
||||
ANGELINA_KEYMAP = no # If Alfa verstion use set to yes.
|
||||
|
||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||
OPT_DEFS += -DOLED_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LED_UNDERGLOW_ENABLE)), yes)
|
||||
RGBLIGHT_ENABLE = yes
|
||||
else
|
||||
RGBLIGHT_ENABLE = no
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LED_ANIMATIONS)), yes)
|
||||
# OPT_DEFS += -DRGBLIGHT_ANIMATIONS
|
||||
OPT_DEFS += -DLED_ANIMATIONS
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(IOS_DEVICE_ENABLE)), yes)
|
||||
OPT_DEFS += -DIOS_DEVICE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LOCAL_GLCDFONT)), yes)
|
||||
OPT_DEFS += -DLOCAL_GLCDFONT
|
||||
endif
|
||||
|
||||
# ifeq ($(strip $(RHYMESTONE_RIGHTHAND)), yes)
|
||||
# OPT_DEFS += -DRHYMESTONE_RIGHTHAND
|
||||
# endif
|
||||
|
||||
ifeq ($(strip $(ANGELINA_KEYMAP)), yes)
|
||||
OPT_DEFS += -DANGELINA_KEYMAP
|
||||
endif
|
||||
|
||||
# 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 you want to change the display of OLED, you need to change here
|
||||
SRC += ./common/oled_helper.c \
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// place overrides here
|
||||
|
||||
#ifdef TAPPING_TERM
|
||||
#undef TAPPING_TERM
|
||||
#endif
|
||||
#define TAPPING_TERM 225
|
||||
#define PREVENT_STUCK_MODIFIERS
|
||||
#define IGNORE_MOD_TAP_INTERRUPT
|
||||
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
#undef MOUSEKEY_INTERVAL
|
||||
#define MOUSEKEY_INTERVAL 1
|
||||
|
||||
#undef MOUSEKEY_TIME_TO_MAX
|
||||
#define MOUSEKEY_TIME_TO_MAX 150
|
||||
|
||||
#undef MOUSEKEY_MAX_SPEED
|
||||
#define MOUSEKEY_MAX_SPEED 3
|
||||
|
||||
#undef MOUSEKEY_MOVE_DELTA
|
||||
#define MOUSEKEY_MOVE_DELTA 4
|
||||
|
||||
#undef MOUSEKEY_DELAY
|
||||
#define MOUSEKEY_DELAY 0
|
||||
#endif
|
||||
|
||||
// Selection of RGBLIGHT MODE to use.
|
||||
#if defined(LED_ANIMATIONS)
|
||||
//#define RGBLIGHT_EFFECT_BREATHING
|
||||
#define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
#define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
//#define RGBLIGHT_EFFECT_SNAKE
|
||||
#define RGBLIGHT_EFFECT_KNIGHT
|
||||
//#define RGBLIGHT_EFFECT_CHRISTMAS
|
||||
#define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
//#define RGBLIGHT_EFFECT_RGB_TEST
|
||||
//#define RGBLIGHT_EFFECT_ALTERNATING
|
||||
#endif
|
@ -0,0 +1,342 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "keymap_jp.h"
|
||||
#include "../common/oled_helper.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
//Following line allows macro to read current RGB settings
|
||||
extern rgblight_config_t rgblight_config;
|
||||
#endif
|
||||
|
||||
extern uint8_t is_master;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
enum layer_number {
|
||||
_BASE = 0,
|
||||
_BASES,
|
||||
_LOWER,
|
||||
_LOWRS,
|
||||
_RAISE,
|
||||
_ADJUST,
|
||||
};
|
||||
|
||||
enum custom_keycodes {
|
||||
BASE = SAFE_RANGE,
|
||||
BASES,
|
||||
LOWER,
|
||||
LOWRS,
|
||||
RAISE,
|
||||
ADJUST,
|
||||
KANJI,
|
||||
RGBRST
|
||||
};
|
||||
|
||||
enum tapdances{
|
||||
TD_SCCL = 0,
|
||||
TD_SLRO,
|
||||
};
|
||||
|
||||
// Layer Mode aliases
|
||||
#define _____ KC_TRNS
|
||||
#define XXXXX KC_NO
|
||||
|
||||
#define KC_TBSF LSFT_T(KC_TAB)
|
||||
// #define KC_SPSF LSFT_T(KC_SPC)
|
||||
#define KC_ALAP LALT_T(KC_APP)
|
||||
#define KC_JEQL LSFT(KC_MINS)
|
||||
#define KC_SFUC LSFT(KC_RO)
|
||||
#define KC_RSBR LSFT(KC_8)
|
||||
#define KC_REBR LSFT(KC_9)
|
||||
|
||||
#define KC_ZSFT LSFT_T(KC_Z)
|
||||
#define KC_ESCT LCTL_T(KC_ESC)
|
||||
#define KC_TBAL LALT_T(KC_TAB)
|
||||
#define KC_11SF LSFT_T(KC_F11)
|
||||
|
||||
#define KC_SCCL TD(TD_SCCL)
|
||||
#define KC_SLRO TD(TD_SLRO)
|
||||
|
||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||
[TD_SCCL] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_QUOT),
|
||||
[TD_SLRO] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_RO),
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[_BASE] = LAYOUT_rs( \
|
||||
// Treadstone48 Rhymestone
|
||||
//,--------------------------------------------------------------------------------------------------------------------. --------------------------------------------.
|
||||
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS, KC_P7, KC_P8, KC_P9, KC_PSLS, KC_NLCK,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------| --------+--------+--------+--------+--------|
|
||||
KC_TBSF, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCCL, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PAST, KC_TAB,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLRO, KC_UP, KC_P1, KC_P2, KC_P3, KC_PMNS, KC_PENT,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
KC_LCTRL, KC_LALT, KC_LGUI, LOWER, KC_BSPC, KC_SPC, RAISE, KC_ALAP, KC_LEFT, KC_DOWN, KC_RGHT, LOWER, KC_P0, KC_PDOT, KC_PPLS, KC_BSPC,\
|
||||
//`--------------------------------------------------------------------------------------------------------------------' --------------------------------------------'
|
||||
KC_DEL \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT_rs( \
|
||||
// Treadstone48 Rhymestone
|
||||
//,--------------------------------------------------------------------------------------------------------------------. --------------------------------------------.
|
||||
_____, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MINS, KC_EQL, KC_JYEN, KC_LBRC, KC_RBRC, KC_DEL, KC_A, KC_B, KC_C, KC_JYEN, KC_HASH,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------| --------+--------+--------+--------+--------|
|
||||
_____, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, XXXXX, XXXXX, KC_SCLN, KC_QUOT, KC_BSLS, _____, KC_D, KC_E, KC_F, KC_PERC, KC_SFUC,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, KC_F11, KC_F12, BASES, KANJI, KC_ENT, XXXXX, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_PGUP, KC_RSBR, KC_REBR, KC_RBRC, KC_QUOT, _____,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, KC_DEL, _____, _____, XXXXX, KC_HOME, KC_PGDN, KC_END, _____, XXXXX, KC_COMM, KC_JEQL, KC_DEL,\
|
||||
//`--------------------------------------------------------------------------------------------------------------------' --------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_BASES] = LAYOUT_rs( \
|
||||
// Treadstone48 Rhymestone
|
||||
//,--------------------------------------------------------------------------------------------------------------------. --------------------------------------------.
|
||||
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS, KC_Q, KC_W, KC_E, KC_R, KC_T,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------| --------+--------+--------+--------+--------|
|
||||
KC_TBSF, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCCL, KC_ENT, KC_A, KC_S, KC_D, KC_F, KC_G,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLRO, KC_UP, KC_ZSFT, KC_X, KC_C, KC_V, KC_B,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
KC_LCTRL, KC_LALT, KC_LGUI, LOWER, KC_BSPC, KC_SPC, RAISE, KC_ALAP, KC_LEFT, KC_DOWN, KC_RGHT, KC_ESCT, KC_TBAL, KC_LGUI, LOWRS, KC_BSPC,\
|
||||
//`--------------------------------------------------------------------------------------------------------------------' --------------------------------------------'
|
||||
KC_DEL \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_LOWRS] = LAYOUT_rs( \
|
||||
// Treadstone48 Rhymestone
|
||||
//,--------------------------------------------------------------------------------------------------------------------. --------------------------------------------.
|
||||
_____, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MINS, KC_EQL, KC_JYEN, KC_LBRC, KC_RBRC, KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------| --------+--------+--------+--------+--------|
|
||||
_____, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, XXXXX, XXXXX, KC_SCLN, KC_QUOT, KC_BSLS, _____, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, KC_F11, KC_F12, BASE, KANJI, KC_ENT, XXXXX, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_PGUP, KC_11SF, KC_F12, BASE, KANJI, KC_ENT,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, KC_DEL, _____, _____, XXXXX, KC_HOME, KC_PGDN, KC_END, _____, _____, _____, _____, KC_DEL,\
|
||||
//`--------------------------------------------------------------------------------------------------------------------' --------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT_rs( \
|
||||
// Treadstone48 Rhymestone
|
||||
//,--------------------------------------------------------------------------------------------------------------------. --------------------------------------------.
|
||||
_____, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------| --------+--------+--------+--------+--------|
|
||||
_____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, KC_4, KC_5, KC_6, KC_QUOT, _____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, KC_1, KC_2, KC_3, KC_RO, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, _____, _____, _____, KC_0, KC_DOT, KC_COMM, KC_SLSH, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//`--------------------------------------------------------------------------------------------------------------------' --------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
),
|
||||
|
||||
[_ADJUST] = LAYOUT_rs( \
|
||||
// Treadstone48 Rhymestone
|
||||
//,--------------------------------------------------------------------------------------------------------------------. --------------------------------------------.
|
||||
XXXXX, RESET, RGBRST, AG_NORM, AG_SWAP, XXXXX, XXXXX, KC_WH_L, KC_WH_U, KC_HOME, KC_PGUP, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+-----------------| --------+--------+--------+--------+--------|
|
||||
XXXXX, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXX, XXXXX, KC_WH_R, KC_WH_D, KC_END, KC_PGDN, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXX, XXXXX, XXXXX, KC_BTN1, KC_BTN2, XXXXX, KC_MS_U, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//|--------+--------+--------+--------+--------+--------|--------+--------+--------+--------+--------+--------+--------| --------+--------+--------+--------+--------|
|
||||
_____, _____, _____, _____, XXXXX, XXXXX, _____, XXXXX, KC_MS_L, KC_MS_D, KC_MS_R, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\
|
||||
//`--------------------------------------------------------------------------------------------------------------------' --------------------------------------------'
|
||||
XXXXX \
|
||||
// ExtraKey: Split backspace key or it is below the enter key.
|
||||
)
|
||||
};
|
||||
|
||||
#define L_BASE _BASE
|
||||
#define L_BASES (1<<_BASES)
|
||||
#define L_LOWER (1<<_LOWER)
|
||||
#define L_LOWRS (1<<_LOWRS)
|
||||
#define L_RAISE (1<<_RAISE)
|
||||
#define L_ADJUST (1<<_ADJUST)
|
||||
#define L_ADJUST_TRI (L_ADJUST|L_RAISE|L_LOWER)
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
typedef struct {
|
||||
uint8_t state;
|
||||
char name[8];
|
||||
}LAYER_DISPLAY_NAME;
|
||||
|
||||
#define LAYER_DISPLAY_MAX 7
|
||||
const LAYER_DISPLAY_NAME layer_display_name[LAYER_DISPLAY_MAX] = {
|
||||
{L_BASE, "Base"},
|
||||
{L_BASE + 1, "Base"},
|
||||
{L_BASES, "BaseSpl"},
|
||||
{L_LOWER, "Lower"},
|
||||
{L_LOWRS, "LowrSpl"},
|
||||
{L_RAISE, "Raise"},
|
||||
{L_ADJUST_TRI, "Adjust"}
|
||||
};
|
||||
|
||||
static inline const char* get_leyer_status(void) {
|
||||
|
||||
for (uint8_t i = 0; i < LAYER_DISPLAY_MAX; ++i) {
|
||||
if (layer_state == 0 && layer_display_name[i].state == default_layer_state) {
|
||||
|
||||
return layer_display_name[i].name;
|
||||
} else if (layer_state != 0 && layer_display_name[i].state == layer_state) {
|
||||
|
||||
return layer_display_name[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
static char layer_status_buf[24] = "Layer state ready.\n";
|
||||
static inline void update_keymap_status(void) {
|
||||
|
||||
snprintf(layer_status_buf, sizeof(layer_status_buf) - 1, "OS:%s Layer:%s\n",
|
||||
keymap_config.swap_lalt_lgui? "win" : "mac", get_leyer_status());
|
||||
}
|
||||
|
||||
static inline void render_keymap_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
matrix_write(matrix, layer_status_buf);
|
||||
}
|
||||
|
||||
#define UPDATE_KEYMAP_STATUS() update_keymap_status()
|
||||
#define RENDER_KEYMAP_STATUS(a) render_keymap_status(a)
|
||||
|
||||
#else
|
||||
|
||||
#define UPDATE_KEYMAP_STATUS()
|
||||
#define RENDER_KEYMAP_STATUS(a)
|
||||
|
||||
#endif
|
||||
|
||||
void update_change_layer(bool pressed, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||
|
||||
pressed ? layer_on(layer1) : layer_off(layer1);
|
||||
IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2) ? layer_on(layer3) : layer_off(layer3);
|
||||
}
|
||||
|
||||
int RGB_current_mode;
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
UPDATE_KEY_STATUS(keycode, record);
|
||||
|
||||
bool result = false;
|
||||
switch (keycode) {
|
||||
case LOWER:
|
||||
update_change_layer(record->event.pressed, _LOWER, _RAISE, _ADJUST);
|
||||
break;
|
||||
case RAISE:
|
||||
update_change_layer(record->event.pressed, _RAISE, _LOWER, _ADJUST);
|
||||
break;
|
||||
case BASE:
|
||||
if (record->event.pressed) {
|
||||
default_layer_set(L_BASE);
|
||||
}
|
||||
break;
|
||||
case BASES:
|
||||
if (record->event.pressed) {
|
||||
default_layer_set(L_BASES);
|
||||
}
|
||||
break;
|
||||
case LOWRS:
|
||||
update_change_layer(record->event.pressed, _LOWRS, _RAISE, _ADJUST);
|
||||
break;
|
||||
case KANJI:
|
||||
if (record->event.pressed) {
|
||||
if (keymap_config.swap_lalt_lgui == false) {
|
||||
register_code(KC_LANG2);
|
||||
} else {
|
||||
SEND_STRING(SS_LALT("`"));
|
||||
}
|
||||
} else {
|
||||
unregister_code(KC_LANG2);
|
||||
}
|
||||
break;
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
case RGB_MOD:
|
||||
if (record->event.pressed) {
|
||||
rgblight_mode(RGB_current_mode);
|
||||
rgblight_step();
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
}
|
||||
break;
|
||||
case RGBRST:
|
||||
if (record->event.pressed) {
|
||||
eeconfig_update_rgblight_default();
|
||||
rgblight_enable();
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
UPDATE_KEYMAP_STATUS();
|
||||
return result;
|
||||
}
|
||||
|
||||
void matrix_init_user(void) {
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
RGB_current_mode = rgblight_config.mode;
|
||||
#endif
|
||||
//SSD1306 OLED init, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
iota_gfx_init(!has_usb()); // turns on the display
|
||||
#endif
|
||||
}
|
||||
|
||||
//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
iota_gfx_task(); // this is what updates the display continuously
|
||||
}
|
||||
|
||||
static inline void matrix_update(struct CharacterMatrix *dest,
|
||||
const struct CharacterMatrix *source) {
|
||||
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
|
||||
memcpy(dest->display, source->display, sizeof(dest->display));
|
||||
dest->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void render_status(struct CharacterMatrix *matrix) {
|
||||
|
||||
UPDATE_LED_STATUS();
|
||||
RENDER_LED_STATUS(matrix);
|
||||
RENDER_KEYMAP_STATUS(matrix);
|
||||
UPDATE_LOCK_STATUS();
|
||||
RENDER_LOCK_STATUS(matrix);
|
||||
RENDER_KEY_STATUS(matrix);
|
||||
}
|
||||
|
||||
void iota_gfx_task_user(void) {
|
||||
struct CharacterMatrix matrix;
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
if (debug_enable) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
matrix_clear(&matrix);
|
||||
if (is_master) {
|
||||
render_status(&matrix);
|
||||
}
|
||||
|
||||
matrix_update(&display, &matrix);
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,5 @@
|
||||
# The like jis type keyboard keymap for treadstone48
|
||||
|
||||
## Description
|
||||
|
||||
## How to use
|
@ -0,0 +1,67 @@
|
||||
|
||||
# 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 = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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.
|
||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing
|
||||
TAP_DANCE_ENABLE = yes
|
||||
|
||||
# If your custom treadstone48 pcb, you can rewrite to yes.
|
||||
OLED_ENABLE = no # OLED_ENABLE
|
||||
LED_UNDERGLOW_ENABLE = yes # LED underglow (Enable WS2812 RGB underlight.)
|
||||
LED_ANIMATIONS = yes # LED animations
|
||||
|
||||
# Other selectable option
|
||||
IOS_DEVICE_ENABLE = no # connect to IOS device (iPad,iPhone)
|
||||
LOCAL_GLCDFONT = no # use each keymaps "font.h" insted of "common/glcdfont.c"
|
||||
RHYMESTONE_RIGHTHAND = no # If connect right hand side of the Rhymestone, set to yes.
|
||||
ANGELINA_KEYMAP = no # If Alfa verstion use set to yes.
|
||||
|
||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||
OPT_DEFS += -DOLED_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LED_UNDERGLOW_ENABLE)), yes)
|
||||
RGBLIGHT_ENABLE = yes
|
||||
else
|
||||
RGBLIGHT_ENABLE = no
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LED_ANIMATIONS)), yes)
|
||||
# OPT_DEFS += -DRGBLIGHT_ANIMATIONS
|
||||
OPT_DEFS += -DLED_ANIMATIONS
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(IOS_DEVICE_ENABLE)), yes)
|
||||
OPT_DEFS += -DIOS_DEVICE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LOCAL_GLCDFONT)), yes)
|
||||
OPT_DEFS += -DLOCAL_GLCDFONT
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RHYMESTONE_RIGHTHAND)), yes)
|
||||
OPT_DEFS += -DRHYMESTONE_RIGHTHAND
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ANGELINA_KEYMAP)), yes)
|
||||
OPT_DEFS += -DANGELINA_KEYMAP
|
||||
endif
|
||||
|
||||
# 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 you want to change the display of OLED, you need to change here
|
||||
SRC += ./common/oled_helper.c \
|
@ -0,0 +1,362 @@
|
||||
/*
|
||||
pins_arduino.h - Pin definition functions for Arduino
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2007 David A. Mellis
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
|
||||
*/
|
||||
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
// Workaround for wrong definitions in "iom32u4.h".
|
||||
// This should be fixed in the AVR toolchain.
|
||||
#undef UHCON
|
||||
#undef UHINT
|
||||
#undef UHIEN
|
||||
#undef UHADDR
|
||||
#undef UHFNUM
|
||||
#undef UHFNUML
|
||||
#undef UHFNUMH
|
||||
#undef UHFLEN
|
||||
#undef UPINRQX
|
||||
#undef UPINTX
|
||||
#undef UPNUM
|
||||
#undef UPRST
|
||||
#undef UPCONX
|
||||
#undef UPCFG0X
|
||||
#undef UPCFG1X
|
||||
#undef UPSTAX
|
||||
#undef UPCFG2X
|
||||
#undef UPIENX
|
||||
#undef UPDATX
|
||||
#undef TCCR2A
|
||||
#undef WGM20
|
||||
#undef WGM21
|
||||
#undef COM2B0
|
||||
#undef COM2B1
|
||||
#undef COM2A0
|
||||
#undef COM2A1
|
||||
#undef TCCR2B
|
||||
#undef CS20
|
||||
#undef CS21
|
||||
#undef CS22
|
||||
#undef WGM22
|
||||
#undef FOC2B
|
||||
#undef FOC2A
|
||||
#undef TCNT2
|
||||
#undef TCNT2_0
|
||||
#undef TCNT2_1
|
||||
#undef TCNT2_2
|
||||
#undef TCNT2_3
|
||||
#undef TCNT2_4
|
||||
#undef TCNT2_5
|
||||
#undef TCNT2_6
|
||||
#undef TCNT2_7
|
||||
#undef OCR2A
|
||||
#undef OCR2_0
|
||||
#undef OCR2_1
|
||||
#undef OCR2_2
|
||||
#undef OCR2_3
|
||||
#undef OCR2_4
|
||||
#undef OCR2_5
|
||||
#undef OCR2_6
|
||||
#undef OCR2_7
|
||||
#undef OCR2B
|
||||
#undef OCR2_0
|
||||
#undef OCR2_1
|
||||
#undef OCR2_2
|
||||
#undef OCR2_3
|
||||
#undef OCR2_4
|
||||
#undef OCR2_5
|
||||
#undef OCR2_6
|
||||
#undef OCR2_7
|
||||
|
||||
#define NUM_DIGITAL_PINS 30
|
||||
#define NUM_ANALOG_INPUTS 12
|
||||
|
||||
#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0)
|
||||
#define TXLED0 PORTD |= (1<<5)
|
||||
#define TXLED1 PORTD &= ~(1<<5)
|
||||
#define RXLED0 PORTB |= (1<<0)
|
||||
#define RXLED1 PORTB &= ~(1<<0)
|
||||
|
||||
static const uint8_t SDA = 2;
|
||||
static const uint8_t SCL = 3;
|
||||
#define LED_BUILTIN 13
|
||||
|
||||
// Map SPI port to 'new' pins D14..D17
|
||||
static const uint8_t SS = 17;
|
||||
static const uint8_t MOSI = 16;
|
||||
static const uint8_t MISO = 14;
|
||||
static const uint8_t SCK = 15;
|
||||
|
||||
// Mapping of analog pins as digital I/O
|
||||
// A6-A11 share with digital pins
|
||||
static const uint8_t ADC0 = 18;
|
||||
static const uint8_t ADC1 = 19;
|
||||
static const uint8_t ADC2 = 20;
|
||||
static const uint8_t ADC3 = 21;
|
||||
static const uint8_t ADC4 = 22;
|
||||
static const uint8_t ADC5 = 23;
|
||||
static const uint8_t ADC6 = 24; // D4
|
||||
static const uint8_t ADC7 = 25; // D6
|
||||
static const uint8_t ADC8 = 26; // D8
|
||||
static const uint8_t ADC9 = 27; // D9
|
||||
static const uint8_t ADC10 = 28; // D10
|
||||
static const uint8_t ADC11 = 29; // D12
|
||||
|
||||
#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
|
||||
#define digitalPinToPCICRbit(p) 0
|
||||
#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
|
||||
#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
|
||||
|
||||
// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
|
||||
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
|
||||
#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
|
||||
|
||||
#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))
|
||||
|
||||
#ifdef ARDUINO_MAIN
|
||||
|
||||
// On the Arduino board, digital pins are also used
|
||||
// for the analog output (software PWM). Analog input
|
||||
// pins are a separate set.
|
||||
|
||||
// ATMEL ATMEGA32U4 / ARDUINO LEONARDO
|
||||
//
|
||||
// D0 PD2 RXD1/INT2
|
||||
// D1 PD3 TXD1/INT3
|
||||
// D2 PD1 SDA SDA/INT1
|
||||
// D3# PD0 PWM8/SCL OC0B/SCL/INT0
|
||||
// D4 A6 PD4 ADC8
|
||||
// D5# PC6 ??? OC3A/#OC4A
|
||||
// D6# A7 PD7 FastPWM #OC4D/ADC10
|
||||
// D7 PE6 INT6/AIN0
|
||||
//
|
||||
// D8 A8 PB4 ADC11/PCINT4
|
||||
// D9# A9 PB5 PWM16 OC1A/#OC4B/ADC12/PCINT5
|
||||
// D10# A10 PB6 PWM16 OC1B/0c4B/ADC13/PCINT6
|
||||
// D11# PB7 PWM8/16 0C0A/OC1C/#RTS/PCINT7
|
||||
// D12 A11 PD6 T1/#OC4D/ADC9
|
||||
// D13# PC7 PWM10 CLK0/OC4A
|
||||
//
|
||||
// A0 D18 PF7 ADC7
|
||||
// A1 D19 PF6 ADC6
|
||||
// A2 D20 PF5 ADC5
|
||||
// A3 D21 PF4 ADC4
|
||||
// A4 D22 PF1 ADC1
|
||||
// A5 D23 PF0 ADC0
|
||||
//
|
||||
// New pins D14..D17 to map SPI port to digital pins
|
||||
//
|
||||
// MISO D14 PB3 MISO,PCINT3
|
||||
// SCK D15 PB1 SCK,PCINT1
|
||||
// MOSI D16 PB2 MOSI,PCINT2
|
||||
// SS D17 PB0 RXLED,SS/PCINT0
|
||||
//
|
||||
// Connected LEDs on board for TX and RX
|
||||
// TXLED D24 PD5 XCK1
|
||||
// RXLED D17 PB0
|
||||
// HWB PE2 HWB
|
||||
|
||||
// these arrays map port names (e.g. port B) to the
|
||||
// appropriate addresses for various functions (e.g. reading
|
||||
// and writing)
|
||||
const uint16_t PROGMEM port_to_mode_PGM[] = {
|
||||
NOT_A_PORT,
|
||||
NOT_A_PORT,
|
||||
(uint16_t) &DDRB,
|
||||
(uint16_t) &DDRC,
|
||||
(uint16_t) &DDRD,
|
||||
(uint16_t) &DDRE,
|
||||
(uint16_t) &DDRF,
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM port_to_output_PGM[] = {
|
||||
NOT_A_PORT,
|
||||
NOT_A_PORT,
|
||||
(uint16_t) &PORTB,
|
||||
(uint16_t) &PORTC,
|
||||
(uint16_t) &PORTD,
|
||||
(uint16_t) &PORTE,
|
||||
(uint16_t) &PORTF,
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM port_to_input_PGM[] = {
|
||||
NOT_A_PORT,
|
||||
NOT_A_PORT,
|
||||
(uint16_t) &PINB,
|
||||
(uint16_t) &PINC,
|
||||
(uint16_t) &PIND,
|
||||
(uint16_t) &PINE,
|
||||
(uint16_t) &PINF,
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
|
||||
PD, // D0 - PD2
|
||||
PD, // D1 - PD3
|
||||
PD, // D2 - PD1
|
||||
PD, // D3 - PD0
|
||||
PD, // D4 - PD4
|
||||
PC, // D5 - PC6
|
||||
PD, // D6 - PD7
|
||||
PE, // D7 - PE6
|
||||
|
||||
PB, // D8 - PB4
|
||||
PB, // D9 - PB5
|
||||
PB, // D10 - PB6
|
||||
PB, // D11 - PB7
|
||||
PD, // D12 - PD6
|
||||
PC, // D13 - PC7
|
||||
|
||||
PB, // D14 - MISO - PB3
|
||||
PB, // D15 - SCK - PB1
|
||||
PB, // D16 - MOSI - PB2
|
||||
PB, // D17 - SS - PB0
|
||||
|
||||
PF, // D18 - A0 - PF7
|
||||
PF, // D19 - A1 - PF6
|
||||
PF, // D20 - A2 - PF5
|
||||
PF, // D21 - A3 - PF4
|
||||
PF, // D22 - A4 - PF1
|
||||
PF, // D23 - A5 - PF0
|
||||
|
||||
PD, // D24 - PD5
|
||||
PD, // D25 / D6 - A7 - PD7
|
||||
PB, // D26 / D8 - A8 - PB4
|
||||
PB, // D27 / D9 - A9 - PB5
|
||||
PB, // D28 / D10 - A10 - PB6
|
||||
PD, // D29 / D12 - A11 - PD6
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
|
||||
_BV(2), // D0 - PD2
|
||||
_BV(3), // D1 - PD3
|
||||
_BV(1), // D2 - PD1
|
||||
_BV(0), // D3 - PD0
|
||||
_BV(4), // D4 - PD4
|
||||
_BV(6), // D5 - PC6
|
||||
_BV(7), // D6 - PD7
|
||||
_BV(6), // D7 - PE6
|
||||
|
||||
_BV(4), // D8 - PB4
|
||||
_BV(5), // D9 - PB5
|
||||
_BV(6), // D10 - PB6
|
||||
_BV(7), // D11 - PB7
|
||||
_BV(6), // D12 - PD6
|
||||
_BV(7), // D13 - PC7
|
||||
|
||||
_BV(3), // D14 - MISO - PB3
|
||||
_BV(1), // D15 - SCK - PB1
|
||||
_BV(2), // D16 - MOSI - PB2
|
||||
_BV(0), // D17 - SS - PB0
|
||||
|
||||
_BV(7), // D18 - A0 - PF7
|
||||
_BV(6), // D19 - A1 - PF6
|
||||
_BV(5), // D20 - A2 - PF5
|
||||
_BV(4), // D21 - A3 - PF4
|
||||
_BV(1), // D22 - A4 - PF1
|
||||
_BV(0), // D23 - A5 - PF0
|
||||
|
||||
_BV(5), // D24 - PD5
|
||||
_BV(7), // D25 / D6 - A7 - PD7
|
||||
_BV(4), // D26 / D8 - A8 - PB4
|
||||
_BV(5), // D27 / D9 - A9 - PB5
|
||||
_BV(6), // D28 / D10 - A10 - PB6
|
||||
_BV(6), // D29 / D12 - A11 - PD6
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
TIMER0B, /* 3 */
|
||||
NOT_ON_TIMER,
|
||||
TIMER3A, /* 5 */
|
||||
TIMER4D, /* 6 */
|
||||
NOT_ON_TIMER,
|
||||
|
||||
NOT_ON_TIMER,
|
||||
TIMER1A, /* 9 */
|
||||
TIMER1B, /* 10 */
|
||||
TIMER0A, /* 11 */
|
||||
|
||||
NOT_ON_TIMER,
|
||||
TIMER4A, /* 13 */
|
||||
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
NOT_ON_TIMER,
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
|
||||
7, // A0 PF7 ADC7
|
||||
6, // A1 PF6 ADC6
|
||||
5, // A2 PF5 ADC5
|
||||
4, // A3 PF4 ADC4
|
||||
1, // A4 PF1 ADC1
|
||||
0, // A5 PF0 ADC0
|
||||
8, // A6 D4 PD4 ADC8
|
||||
10, // A7 D6 PD7 ADC10
|
||||
11, // A8 D8 PB4 ADC11
|
||||
12, // A9 D9 PB5 ADC12
|
||||
13, // A10 D10 PB6 ADC13
|
||||
9 // A11 D12 PD6 ADC9
|
||||
};
|
||||
|
||||
#endif /* ARDUINO_MAIN */
|
||||
|
||||
// These serial port names are intended to allow libraries and architecture-neutral
|
||||
// sketches to automatically default to the correct port name for a particular type
|
||||
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
|
||||
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
|
||||
//
|
||||
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
|
||||
//
|
||||
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
|
||||
//
|
||||
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
|
||||
//
|
||||
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
|
||||
// pins are NOT connected to anything by default.
|
||||
#define SERIAL_PORT_MONITOR Serial
|
||||
#define SERIAL_PORT_USBVIRTUAL Serial
|
||||
#define SERIAL_PORT_HARDWARE Serial1
|
||||
#define SERIAL_PORT_HARDWARE_OPEN Serial1
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
@ -0,0 +1,18 @@
|
||||
# treadstone48
|
||||
|
||||
![treadstone48](https://github.com/marksard/Keyboards/raw/master/_image/20181219-PC190003.jpg)
|
||||
|
||||
A 47 (or 48) keys Symmetric Staggered keyboard.
|
||||
|
||||
Keyboard Maintainer: [marksard](https://github.com/marksard)
|
||||
Hardware Supported: The PCBs, controllers supported
|
||||
Hardware Availability: links to where you can find this hardware
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make treadstone48:default
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
||||
|
||||
[Build guide](https://github.com/marksard/Keyboards/blob/master/treadstpne48/documents/treadstone48_buildguide.md)
|
||||
[Firmware](https://github.com/marksard/qmk_firmware/tree/my_customize/keyboards/treadstone48)
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
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 REV1_CONFIG_H
|
||||
#define REV1_CONFIG_H
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0xDFA3
|
||||
#define DEVICE_VER 0x0010
|
||||
#define MANUFACTURER marksard
|
||||
#define PRODUCT treadstone48
|
||||
#define DESCRIPTION Symmetrical staggered 47+1 Keys Keyboard
|
||||
|
||||
#define PREVENT_STUCK_MODIFIERS
|
||||
#define TAPPING_FORCE_HOLD
|
||||
#define TAPPING_TERM 150
|
||||
|
||||
/* Use I2C or Serial */
|
||||
#define USE_I2C
|
||||
#define USE_SERIAL
|
||||
//#define USE_MATRIX_I2C
|
||||
|
||||
/* Select hand configuration */
|
||||
#define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
||||
|
||||
// OLED support
|
||||
// see ./rules.mk: OLED_ENABLE=yes or no
|
||||
#ifdef OLED_ENABLE
|
||||
#define SSD1306OLED
|
||||
#endif
|
||||
|
||||
/* key matrix size */
|
||||
// Rows are doubled-up
|
||||
#define MATRIX_ROWS 16
|
||||
#define MATRIX_ROW_PINS { F4, F5, F6, F7, B1, B3, B2, B6 }
|
||||
|
||||
// wiring of each half
|
||||
#define MATRIX_COLS 6
|
||||
#define MATRIX_COL_PINS { D4, C6, D7, E6, B4, B5 }
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
// #define BACKLIGHT_LEVELS 3
|
||||
|
||||
/* 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 D3
|
||||
#define RGBLIGHT_TIMER
|
||||
//#define RGBLED_NUM 12 // Number of LEDs. see ./keymaps/default/config.h
|
||||
#define ws2812_PORTREG PORTD
|
||||
#define ws2812_DDRREG DDRD
|
||||
|
||||
// treadstone48 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
|
||||
#define RGBLED_NUM 12
|
||||
|
||||
#ifndef IOS_DEVICE_ENABLE
|
||||
#define RGBLIGHT_LIMIT_VAL 180
|
||||
#define RGBLIGHT_VAL_STEP 17
|
||||
#else
|
||||
#define RGBLIGHT_LIMIT_VAL 50
|
||||
#define RGBLIGHT_VAL_STEP 4
|
||||
#endif
|
||||
#define RGBLIGHT_HUE_STEP 10
|
||||
#define RGBLIGHT_SAT_STEP 17
|
||||
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(IOS_DEVICE_ENABLE)
|
||||
// USB_MAX_POWER_CONSUMPTION value for treadstone48 keyboard
|
||||
// 120 RGBoff, OLEDoff
|
||||
// 120 OLED
|
||||
// 330 RGB 6
|
||||
// 300 RGB 32
|
||||
// 310 OLED & RGB 32
|
||||
#define USB_MAX_POWER_CONSUMPTION 400
|
||||
#else
|
||||
// fix iPhone and iPad power adapter issue
|
||||
// iOS device need lessthan 100
|
||||
#define USB_MAX_POWER_CONSUMPTION 100
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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,261 @@
|
||||
{
|
||||
"keyboard_name": "Treadstone48",
|
||||
"url": "https://github.com/marksard/Keyboards",
|
||||
"maintainer": "marksard",
|
||||
"width": 14.75,
|
||||
"height": 4,
|
||||
"layouts": {
|
||||
"LAYOUT_base": {
|
||||
"layout": [
|
||||
{
|
||||
"label": "Esc",
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "Q",
|
||||
"x": 2.25,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "W",
|
||||
"x": 3.25,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "E",
|
||||
"x": 4.25,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "R",
|
||||
"x": 5.25,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "T",
|
||||
"x": 6.25,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "Y",
|
||||
"x": 7.75,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "U",
|
||||
"x": 8.75,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "I",
|
||||
"x": 9.75,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "O",
|
||||
"x": 10.75,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "P",
|
||||
"x": 11.75,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "-",
|
||||
"x": 13.75,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"label": "Tab",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1.5
|
||||
},
|
||||
{
|
||||
"label": "A",
|
||||
"x": 2.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "S",
|
||||
"x": 3.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "D",
|
||||
"x": 4.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "F",
|
||||
"x": 5.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "G",
|
||||
"x": 6.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "H",
|
||||
"x": 7.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "J",
|
||||
"x": 8.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "K",
|
||||
"x": 9.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "L",
|
||||
"x": 10.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": ":",
|
||||
"x": 11.5,
|
||||
"y": 1
|
||||
},
|
||||
{
|
||||
"label": "Enter",
|
||||
"x": 12.5,
|
||||
"y": 1,
|
||||
"w": 2.25
|
||||
},
|
||||
{
|
||||
"label": "Shift",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 2.25
|
||||
},
|
||||
{
|
||||
"label": "Z",
|
||||
"x": 2.25,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "X",
|
||||
"x": 3.25,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "C",
|
||||
"x": 4.25,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "V",
|
||||
"x": 5.25,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "B",
|
||||
"x": 6.25,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "N",
|
||||
"x": 7.75,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "M",
|
||||
"x": 8.75,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "<",
|
||||
"x": 9.75,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": ">",
|
||||
"x": 10.75,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "?",
|
||||
"x": 11.75,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "\u2191",
|
||||
"x": 12.75,
|
||||
"y": 2
|
||||
},
|
||||
{
|
||||
"label": "Ctrl",
|
||||
"x": 0.75,
|
||||
"y": 3,
|
||||
"w": 1.25
|
||||
},
|
||||
{
|
||||
"label": "Win",
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 1.25
|
||||
},
|
||||
{
|
||||
"label": "Alt",
|
||||
"x": 3.25,
|
||||
"y": 3,
|
||||
"w": 1.25
|
||||
},
|
||||
{
|
||||
"label": "Lower",
|
||||
"x": 4.5,
|
||||
"y": 3
|
||||
},
|
||||
{
|
||||
"label": "BackSpace",
|
||||
"x": 5.5,
|
||||
"y": 3,
|
||||
"w": 2
|
||||
},
|
||||
{
|
||||
"x": 7.5,
|
||||
"y": 3,
|
||||
"w": 2
|
||||
},
|
||||
{
|
||||
"label": "Raise",
|
||||
"x": 9.5,
|
||||
"y": 3
|
||||
},
|
||||
{
|
||||
"label": "Menu",
|
||||
"x": 10.5,
|
||||
"y": 3,
|
||||
"w": 1.25
|
||||
},
|
||||
{
|
||||
"label": "\u2190",
|
||||
"x": 11.75,
|
||||
"y": 3
|
||||
},
|
||||
{
|
||||
"label": "\u2193",
|
||||
"x": 12.75,
|
||||
"y": 3
|
||||
},
|
||||
{
|
||||
"label": "\u2192",
|
||||
"x": 13.75,
|
||||
"y": 3
|
||||
},
|
||||
{
|
||||
"label": "_",
|
||||
"x": 12.75,
|
||||
"y": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,357 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* scan matrix
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#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"
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
# include "i2c.h"
|
||||
#else // USE_SERIAL
|
||||
# include "split_scomm.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;
|
||||
uint8_t is_master = 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);
|
||||
static uint8_t matrix_master_scan(void);
|
||||
|
||||
|
||||
__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;
|
||||
TXLED0;
|
||||
RXLED0;
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
matrix_debouncing[i] = 0;
|
||||
}
|
||||
|
||||
is_master = has_usb();
|
||||
|
||||
matrix_init_quantum();
|
||||
}
|
||||
|
||||
uint8_t _matrix_scan(void)
|
||||
{
|
||||
// Right hand is stored after the left in the matirx 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_MATRIX_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) {
|
||||
int i;
|
||||
for (i = 0; i < ROWS_PER_HAND-1; ++i) {
|
||||
matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
|
||||
}
|
||||
matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
|
||||
i2c_master_stop();
|
||||
} else {
|
||||
i2c_error: // the cable is disconnceted, or something else went wrong
|
||||
i2c_reset_state();
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // USE_SERIAL
|
||||
|
||||
int serial_transaction(int master_changed) {
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int ret=serial_update_buffers(master_changed);
|
||||
#else
|
||||
int ret=serial_update_buffers();
|
||||
#endif
|
||||
if (ret ) {
|
||||
if(ret==2) RXLED1;
|
||||
return 1;
|
||||
}
|
||||
RXLED0;
|
||||
memcpy(&matrix[slaveOffset],
|
||||
(void *)serial_slave_buffer, sizeof(serial_slave_buffer));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
if (is_master) {
|
||||
matrix_master_scan();
|
||||
}else{
|
||||
matrix_slave_scan();
|
||||
int offset = (isLeftHand) ? ROWS_PER_HAND : 0;
|
||||
memcpy(&matrix[offset],
|
||||
(void *)serial_master_buffer, sizeof(serial_master_buffer));
|
||||
matrix_scan_quantum();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t matrix_master_scan(void) {
|
||||
|
||||
int ret = _matrix_scan();
|
||||
int mchanged = 1;
|
||||
|
||||
int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
// for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */
|
||||
// i2c_slave_buffer[i] = matrix[offset+i];
|
||||
// }
|
||||
#else // USE_SERIAL
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
mchanged = memcmp((void *)serial_master_buffer,
|
||||
&matrix[offset], sizeof(serial_master_buffer));
|
||||
#endif
|
||||
memcpy((void *)serial_master_buffer,
|
||||
&matrix[offset], sizeof(serial_master_buffer));
|
||||
#endif
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
if( i2c_transaction() ) {
|
||||
#else // USE_SERIAL
|
||||
if( serial_transaction(mchanged) ) {
|
||||
#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_MATRIX_I2C
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */
|
||||
i2c_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
#else // USE_SERIAL
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int change = 0;
|
||||
#endif
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
if( serial_slave_buffer[i] != matrix[offset+i] )
|
||||
change = 1;
|
||||
#endif
|
||||
serial_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
slave_buffer_change_count += change;
|
||||
#endif
|
||||
#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,15 @@
|
||||
#include "treadstone48.h"
|
||||
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
|
||||
matrix_init_user();
|
||||
};
|
||||
|
@ -0,0 +1,202 @@
|
||||
#ifndef REV1_H
|
||||
#define REV1_CONFIG_H
|
||||
|
||||
#include "../treadstone48.h"
|
||||
|
||||
//void promicro_bootloader_jmp(bool program);
|
||||
#include "quantum.h"
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
//rgb led driver
|
||||
#include "ws2812.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_I2C
|
||||
#include <stddef.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// full Keymap
|
||||
// (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left)
|
||||
#define LAYOUT_full( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, R00, R01, R02, R03, R04, R05, R40, R41, R42, R43, R44, R45, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, R10, R11, R12, R13, R14, R15, R50, R51, R52, R53, R54, R55, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, R20, R21, R22, R23, R24, R25, R60, R61, R62, R63, R64, R65, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, R30, R31, R32, R33, R34, R35, R70, R71, R72, R73, R74, R75 \
|
||||
) \
|
||||
{ \
|
||||
{ L45, L44, L43, L42, L41, L40 }, \
|
||||
{ L55, L54, L53, L52, L51, L50 }, \
|
||||
{ L65, L64, L63, L62, L61, L60 }, \
|
||||
{ L75, L74, L73, L72, L71, L70 }, \
|
||||
{ L05, L04, L03, L02, L01, L00 }, \
|
||||
{ L15, L14, L13, L12, L11, L10 }, \
|
||||
{ L25, L24, L23, L22, L21, L20 }, \
|
||||
{ L35, L34, L33, L32, L31, L30 }, \
|
||||
{ R45, R44, R43, R42, R41, R40 }, \
|
||||
{ R55, R54, R53, R52, R51, R50 }, \
|
||||
{ R65, R64, R63, R62, R61, R60 }, \
|
||||
{ R75, R74, R73, R72, R71, R70 }, \
|
||||
{ R05, R04, R03, R02, R01, R00 }, \
|
||||
{ R15, R14, R13, R12, R11, R10 }, \
|
||||
{ R25, R24, R23, R22, R21, R20 }, \
|
||||
{ R35, R34, R33, R32, R31, R30 }, \
|
||||
}
|
||||
|
||||
#define K_N KC_NO
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// When only use Treadstone48.
|
||||
// L75 is ExtraKey
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#define LAYOUT_base( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75 \
|
||||
) \
|
||||
LAYOUT_full( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N \
|
||||
)
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_base_kc( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75 \
|
||||
) \
|
||||
LAYOUT_base( \
|
||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##L40, KC_##L41, KC_##L42, KC_##L43, KC_##L44, KC_##L45, \
|
||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##L50, KC_##L51, KC_##L52, KC_##L53, KC_##L54, KC_##L55, \
|
||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##L60, KC_##L61, KC_##L62, KC_##L63, KC_##L64, KC_##L65, \
|
||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##L70, KC_##L71, KC_##L72, KC_##L73, KC_##L74, KC_##L75 \
|
||||
)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// When connecting Rhymestone to Treadstone48.
|
||||
// L75 is ExtraKey
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#define LAYOUT_rs( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, R40, R41, R42, R43, R44, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, R50, R51, R52, R53, R54, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, R60, R61, R62, R63, R64, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, R70, R71, R72, R73, R74, L75 \
|
||||
) \
|
||||
LAYOUT_full( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R44, R43, R42, R41, R40, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R54, R53, R52, R51, R50, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R64, R63, R62, R61, R60, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R74, R73, R72, R71, R70 \
|
||||
)
|
||||
|
||||
// When use right hand side of the Rhymestone.
|
||||
#ifdef RHYMESTONE_RIGHTHAND
|
||||
#undef LAYOUT_rs
|
||||
#define LAYOUT_rs( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, R40, R41, R42, R43, R44, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, R50, R51, R52, R53, R54, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, R60, R61, R62, R63, R64, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, R70, R71, R72, R73, R74, L75 \
|
||||
) \
|
||||
LAYOUT_full( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R40, R41, R42, R43, R44, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R50, R51, R52, R53, R54, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R60, R61, R62, R63, R64, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R70, R71, R72, R73, R74 \
|
||||
)
|
||||
#endif
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_rs_kc( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, R40, R41, R42, R43, R44, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, R50, R51, R52, R53, R54, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, R60, R61, R62, R63, R64, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, R70, R71, R72, R73, R74 \
|
||||
) \
|
||||
LAYOUT_rs( \
|
||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##L40, KC_##L41, KC_##L42, KC_##L43, KC_##L44, KC_##L45, KC_##R40, KC_##R41, KC_##R42, KC_##R43, KC_##R44, \
|
||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##L50, KC_##L51, KC_##L52, KC_##L53, KC_##L54, KC_##L55, KC_##R50, KC_##R51, KC_##R52, KC_##R53, KC_##R54, \
|
||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##L60, KC_##L61, KC_##L62, KC_##L63, KC_##L64, KC_##L65, KC_##R60, KC_##R61, KC_##R62, KC_##R63, KC_##R64, \
|
||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##L70, KC_##L71, KC_##L72, KC_##L73, KC_##L74, KC_##L75, KC_##R70, KC_##R71, KC_##R72, KC_##R73, KC_##R74 \
|
||||
)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Alpha version keymap.
|
||||
// L30 is ExtraKey
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef ANGELINA_KEYMAP
|
||||
#undef LAYOUT_base
|
||||
#undef LAYOUT_base_kc
|
||||
#undef LAYOUT_rs
|
||||
#undef LAYOUT_rs_kc
|
||||
|
||||
#define LAYOUT_base( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, \
|
||||
L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, L30 \
|
||||
) \
|
||||
LAYOUT_full( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N, K_N \
|
||||
)
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_base_kc( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75 \
|
||||
) \
|
||||
LAYOUT_base( \
|
||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##L40, KC_##L41, KC_##L42, KC_##L43, KC_##L44, KC_##L45, \
|
||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##L50, KC_##L51, KC_##L52, KC_##L53, KC_##L54, KC_##L55, \
|
||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##L60, KC_##L61, KC_##L62, KC_##L63, KC_##L64, KC_##L65, \
|
||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##L70, KC_##L71, KC_##L72, KC_##L73, KC_##L74, KC_##L75 \
|
||||
)
|
||||
|
||||
#define LAYOUT_rs( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, R40, R41, R42, R43, R44, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, R50, R51, R52, R53, R54, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, R60, R61, R62, R63, R64, \
|
||||
L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, R70, R71, R72, R73, R74, L30 \
|
||||
) \
|
||||
LAYOUT_full( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R44, R43, R42, R41, R40, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R54, R53, R52, R51, R50, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R64, R63, R62, R61, R60, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, K_N, K_N, K_N, K_N, K_N, K_N, K_N, R74, R73, R72, R71, R70 \
|
||||
)
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_rs_kc( \
|
||||
L00, L01, L02, L03, L04, L05, L40, L41, L42, L43, L44, L45, R40, R41, R42, R43, R44, \
|
||||
L10, L11, L12, L13, L14, L15, L50, L51, L52, L53, L54, L55, R50, R51, R52, R53, R54, \
|
||||
L20, L21, L22, L23, L24, L25, L60, L61, L62, L63, L64, L65, R60, R61, R62, R63, R64, \
|
||||
L30, L31, L32, L33, L34, L35, L70, L71, L72, L73, L74, L75, R70, R71, R72, R73, R74 \
|
||||
) \
|
||||
LAYOUT_rs( \
|
||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##L40, KC_##L41, KC_##L42, KC_##L43, KC_##L44, KC_##L45, KC_##R40, KC_##R41, KC_##R42, KC_##R43, KC_##R44, \
|
||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##L50, KC_##L51, KC_##L52, KC_##L53, KC_##L54, KC_##L55, KC_##R50, KC_##R51, KC_##R52, KC_##R53, KC_##R54, \
|
||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##L60, KC_##L61, KC_##L62, KC_##L63, KC_##L64, KC_##L65, KC_##R60, KC_##R61, KC_##R62, KC_##R63, KC_##R64, \
|
||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##L70, KC_##L71, KC_##L72, KC_##L73, KC_##L74, KC_##L75, KC_##R70, KC_##R71, KC_##R72, KC_##R73, KC_##R74 \
|
||||
)
|
||||
|
||||
#endif
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
@ -0,0 +1,3 @@
|
||||
SRC += rev1/matrix.c
|
||||
SRC += rev1/split_util.c
|
||||
SRC += rev1/split_scomm.c
|
@ -0,0 +1,8 @@
|
||||
//// #error rev2 serial config
|
||||
|
||||
#ifndef SOFT_SERIAL_PIN
|
||||
/* Soft Serial defines */
|
||||
#define SOFT_SERIAL_PIN D2
|
||||
|
||||
#define SERIAL_USE_MULTI_TRANSACTION
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
#ifndef SERIAL_CONFIG_SIMPLEAPI_H
|
||||
#define SERIAL_CONFIG_SIMPLEAPI_H
|
||||
|
||||
#undef SERIAL_USE_MULTI_TRANSACTION
|
||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
|
||||
#endif // SERIAL_CONFIG_SIMPLEAPI_H
|
@ -0,0 +1,92 @@
|
||||
#ifdef USE_SERIAL
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
/* --- USE flexible API (using multi-type transaction function) --- */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <split_scomm.h>
|
||||
#include "serial.h"
|
||||
#ifdef CONSOLE_ENABLE
|
||||
#include <print.h>
|
||||
#endif
|
||||
|
||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||
uint8_t volatile status_com = 0;
|
||||
uint8_t volatile status1 = 0;
|
||||
uint8_t slave_buffer_change_count = 0;
|
||||
uint8_t s_change_old = 0xff;
|
||||
uint8_t s_change_new = 0xff;
|
||||
|
||||
SSTD_t transactions[] = {
|
||||
#define GET_SLAVE_STATUS 0
|
||||
/* master buffer not changed, only recive slave_buffer_change_count */
|
||||
{ (uint8_t *)&status_com,
|
||||
0, NULL,
|
||||
sizeof(slave_buffer_change_count), &slave_buffer_change_count,
|
||||
},
|
||||
#define PUT_MASTER_GET_SLAVE_STATUS 1
|
||||
/* master buffer changed need send, and recive slave_buffer_change_count */
|
||||
{ (uint8_t *)&status_com,
|
||||
sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer,
|
||||
sizeof(slave_buffer_change_count), &slave_buffer_change_count,
|
||||
},
|
||||
#define GET_SLAVE_BUFFER 2
|
||||
/* recive serial_slave_buffer */
|
||||
{ (uint8_t *)&status1,
|
||||
0, NULL,
|
||||
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
|
||||
}
|
||||
};
|
||||
|
||||
void serial_master_init(void)
|
||||
{
|
||||
soft_serial_initiator_init(transactions, TID_LIMIT(transactions));
|
||||
}
|
||||
|
||||
void serial_slave_init(void)
|
||||
{
|
||||
soft_serial_target_init(transactions, TID_LIMIT(transactions));
|
||||
}
|
||||
|
||||
// 0 => no error
|
||||
// 1 => slave did not respond
|
||||
// 2 => checksum error
|
||||
int serial_update_buffers(int master_update)
|
||||
{
|
||||
int status, smatstatus;
|
||||
static int need_retry = 0;
|
||||
|
||||
if( s_change_old != s_change_new ) {
|
||||
smatstatus = soft_serial_transaction(GET_SLAVE_BUFFER);
|
||||
if( smatstatus == TRANSACTION_END ) {
|
||||
s_change_old = s_change_new;
|
||||
#ifdef CONSOLE_ENABLE
|
||||
uprintf("slave matrix = %b %b %b %b %b\n",
|
||||
serial_slave_buffer[0], serial_slave_buffer[1],
|
||||
serial_slave_buffer[2], serial_slave_buffer[3],
|
||||
serial_slave_buffer[4] );
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// serial_slave_buffer dosen't change
|
||||
smatstatus = TRANSACTION_END; // dummy status
|
||||
}
|
||||
|
||||
if( !master_update && !need_retry) {
|
||||
status = soft_serial_transaction(GET_SLAVE_STATUS);
|
||||
} else {
|
||||
status = soft_serial_transaction(PUT_MASTER_GET_SLAVE_STATUS);
|
||||
}
|
||||
if( status == TRANSACTION_END ) {
|
||||
s_change_new = slave_buffer_change_count;
|
||||
need_retry = 0;
|
||||
} else {
|
||||
need_retry = 1;
|
||||
}
|
||||
return smatstatus;
|
||||
}
|
||||
|
||||
#endif // SERIAL_USE_MULTI_TRANSACTION
|
||||
#endif /* USE_SERIAL */
|
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
/* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */
|
||||
#include "serial.h"
|
||||
|
||||
#else
|
||||
/* --- USE flexible API (using multi-type transaction function) --- */
|
||||
// Buffers for master - slave communication
|
||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
|
||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||
extern uint8_t slave_buffer_change_count;
|
||||
|
||||
void serial_master_init(void);
|
||||
void serial_slave_init(void);
|
||||
int serial_update_buffers(int master_changed);
|
||||
|
||||
#endif
|
@ -0,0 +1,70 @@
|
||||
#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"
|
||||
|
||||
#ifdef USE_MATRIX_I2C
|
||||
# include "i2c.h"
|
||||
#else
|
||||
# include "split_scomm.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_MATRIX_I2C
|
||||
i2c_master_init();
|
||||
#else
|
||||
serial_master_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_slave_setup(void) {
|
||||
|
||||
#ifdef USE_MATRIX_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();
|
||||
}
|
||||
|
||||
// this code runs before the usb and keyboard is initialized
|
||||
void matrix_setup(void) {
|
||||
split_keyboard_setup();
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#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 matrix_master_OLED_init (void);
|
@ -0,0 +1,73 @@
|
||||
SRC += i2c.c
|
||||
SRC += serial.c
|
||||
SRC += ssd1306.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 = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # 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.
|
||||
SUBPROJECT_rev1 = no
|
||||
USE_I2C = yes
|
||||
# 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
|
||||
|
||||
DEFAULT_FOLDER = treadstone48/rev1
|
@ -0,0 +1,590 @@
|
||||
/*
|
||||
* WARNING: be careful changing this code, it is very timing dependent
|
||||
*
|
||||
* 2018-10-28 checked
|
||||
* avr-gcc 4.9.2
|
||||
* avr-gcc 5.4.0
|
||||
* avr-gcc 7.3.0
|
||||
*/
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000
|
||||
#endif
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "serial.h"
|
||||
//#include <pro_micro.h>
|
||||
|
||||
#ifdef SOFT_SERIAL_PIN
|
||||
|
||||
#ifdef __AVR_ATmega32U4__
|
||||
// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
|
||||
#ifdef USE_I2C
|
||||
#if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
|
||||
#error Using ATmega32U4 I2C, so can not use PD0, PD1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
|
||||
#define SERIAL_PIN_DDR DDRD
|
||||
#define SERIAL_PIN_PORT PORTD
|
||||
#define SERIAL_PIN_INPUT PIND
|
||||
#if SOFT_SERIAL_PIN == D0
|
||||
#define SERIAL_PIN_MASK _BV(PD0)
|
||||
#define EIMSK_BIT _BV(INT0)
|
||||
#define EICRx_BIT (~(_BV(ISC00) | _BV(ISC01)))
|
||||
#define SERIAL_PIN_INTERRUPT INT0_vect
|
||||
#elif SOFT_SERIAL_PIN == D1
|
||||
#define SERIAL_PIN_MASK _BV(PD1)
|
||||
#define EIMSK_BIT _BV(INT1)
|
||||
#define EICRx_BIT (~(_BV(ISC10) | _BV(ISC11)))
|
||||
#define SERIAL_PIN_INTERRUPT INT1_vect
|
||||
#elif SOFT_SERIAL_PIN == D2
|
||||
#define SERIAL_PIN_MASK _BV(PD2)
|
||||
#define EIMSK_BIT _BV(INT2)
|
||||
#define EICRx_BIT (~(_BV(ISC20) | _BV(ISC21)))
|
||||
#define SERIAL_PIN_INTERRUPT INT2_vect
|
||||
#elif SOFT_SERIAL_PIN == D3
|
||||
#define SERIAL_PIN_MASK _BV(PD3)
|
||||
#define EIMSK_BIT _BV(INT3)
|
||||
#define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31)))
|
||||
#define SERIAL_PIN_INTERRUPT INT3_vect
|
||||
#endif
|
||||
#elif SOFT_SERIAL_PIN == E6
|
||||
#define SERIAL_PIN_DDR DDRE
|
||||
#define SERIAL_PIN_PORT PORTE
|
||||
#define SERIAL_PIN_INPUT PINE
|
||||
#define SERIAL_PIN_MASK _BV(PE6)
|
||||
#define EIMSK_BIT _BV(INT6)
|
||||
#define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61)))
|
||||
#define SERIAL_PIN_INTERRUPT INT6_vect
|
||||
#else
|
||||
#error invalid SOFT_SERIAL_PIN value
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error serial.c now support ATmega32U4 only
|
||||
#endif
|
||||
|
||||
//////////////// for backward compatibility ////////////////////////////////
|
||||
#if !defined(SERIAL_USE_SINGLE_TRANSACTION) && !defined(SERIAL_USE_MULTI_TRANSACTION)
|
||||
/* --- USE OLD API (compatible with let's split serial.c) */
|
||||
#if SERIAL_SLAVE_BUFFER_LENGTH > 0
|
||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||
#endif
|
||||
#if SERIAL_MASTER_BUFFER_LENGTH > 0
|
||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||
#endif
|
||||
uint8_t volatile status0 = 0;
|
||||
|
||||
SSTD_t transactions[] = {
|
||||
{ (uint8_t *)&status0,
|
||||
#if SERIAL_MASTER_BUFFER_LENGTH > 0
|
||||
sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer,
|
||||
#else
|
||||
0, (uint8_t *)NULL,
|
||||
#endif
|
||||
#if SERIAL_SLAVE_BUFFER_LENGTH > 0
|
||||
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
|
||||
#else
|
||||
0, (uint8_t *)NULL,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
void serial_master_init(void)
|
||||
{ soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
|
||||
|
||||
void serial_slave_init(void)
|
||||
{ soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
|
||||
|
||||
// 0 => no error
|
||||
// 1 => slave did not respond
|
||||
// 2 => checksum error
|
||||
int serial_update_buffers()
|
||||
{
|
||||
int result;
|
||||
result = soft_serial_transaction();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // end of OLD API (compatible with let's split serial.c)
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#define NO_INLINE __attribute__((noinline))
|
||||
#define _delay_sub_us(x) __builtin_avr_delay_cycles(x)
|
||||
|
||||
// parity check
|
||||
#define ODD_PARITY 1
|
||||
#define EVEN_PARITY 0
|
||||
#define PARITY EVEN_PARITY
|
||||
|
||||
#ifdef SERIAL_DELAY
|
||||
// custom setup in config.h
|
||||
// #define TID_SEND_ADJUST 2
|
||||
// #define SERIAL_DELAY 6 // micro sec
|
||||
// #define READ_WRITE_START_ADJUST 30 // cycles
|
||||
// #define READ_WRITE_WIDTH_ADJUST 8 // cycles
|
||||
#else
|
||||
// ============ Standard setups ============
|
||||
|
||||
#ifndef SELECT_SOFT_SERIAL_SPEED
|
||||
#define SELECT_SOFT_SERIAL_SPEED 1
|
||||
// 0: about 189kbps
|
||||
// 1: about 137kbps (default)
|
||||
// 2: about 75kbps
|
||||
// 3: about 39kbps
|
||||
// 4: about 26kbps
|
||||
// 5: about 20kbps
|
||||
#endif
|
||||
|
||||
#if __GNUC__ < 6
|
||||
#define TID_SEND_ADJUST 14
|
||||
#else
|
||||
#define TID_SEND_ADJUST 2
|
||||
#endif
|
||||
|
||||
#if SELECT_SOFT_SERIAL_SPEED == 0
|
||||
// Very High speed
|
||||
#define SERIAL_DELAY 4 // micro sec
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_START_ADJUST 33 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_START_ADJUST 34 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 1
|
||||
// High speed
|
||||
#define SERIAL_DELAY 6 // micro sec
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_START_ADJUST 33 // cycles
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 2
|
||||
// Middle speed
|
||||
#define SERIAL_DELAY 12 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 3
|
||||
// Low speed
|
||||
#define SERIAL_DELAY 24 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 4
|
||||
// Very Low speed
|
||||
#define SERIAL_DELAY 36 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#elif SELECT_SOFT_SERIAL_SPEED == 5
|
||||
// Ultra Low speed
|
||||
#define SERIAL_DELAY 48 // micro sec
|
||||
#define READ_WRITE_START_ADJUST 30 // cycles
|
||||
#if __GNUC__ < 6
|
||||
#define READ_WRITE_WIDTH_ADJUST 3 // cycles
|
||||
#else
|
||||
#define READ_WRITE_WIDTH_ADJUST 7 // cycles
|
||||
#endif
|
||||
#else
|
||||
#error invalid SELECT_SOFT_SERIAL_SPEED value
|
||||
#endif /* SELECT_SOFT_SERIAL_SPEED */
|
||||
#endif /* SERIAL_DELAY */
|
||||
|
||||
#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2)
|
||||
#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2)
|
||||
|
||||
#define SLAVE_INT_WIDTH_US 1
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
#define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
|
||||
#else
|
||||
#define SLAVE_INT_ACK_WIDTH_UNIT 2
|
||||
#define SLAVE_INT_ACK_WIDTH 4
|
||||
#endif
|
||||
|
||||
static SSTD_t *Transaction_table = NULL;
|
||||
static uint8_t Transaction_table_size = 0;
|
||||
|
||||
inline static void serial_delay(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay(void) {
|
||||
_delay_us(SERIAL_DELAY);
|
||||
}
|
||||
|
||||
inline static void serial_delay_half1(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay_half1(void) {
|
||||
_delay_us(SERIAL_DELAY_HALF1);
|
||||
}
|
||||
|
||||
inline static void serial_delay_half2(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_delay_half2(void) {
|
||||
_delay_us(SERIAL_DELAY_HALF2);
|
||||
}
|
||||
|
||||
inline static void serial_output(void) ALWAYS_INLINE;
|
||||
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_with_pullup(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_input_with_pullup(void) {
|
||||
SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static uint8_t serial_read_pin(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
uint8_t serial_read_pin(void) {
|
||||
return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
|
||||
}
|
||||
|
||||
inline static void serial_low(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_low(void) {
|
||||
SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static void serial_high(void) ALWAYS_INLINE;
|
||||
inline static
|
||||
void serial_high(void) {
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size)
|
||||
{
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size)
|
||||
{
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
serial_input_with_pullup();
|
||||
|
||||
// Enable INT0-INT3,INT6
|
||||
EIMSK |= EIMSK_BIT;
|
||||
#if SERIAL_PIN_MASK == _BV(PE6)
|
||||
// Trigger on falling edge of INT6
|
||||
EICRB &= EICRx_BIT;
|
||||
#else
|
||||
// Trigger on falling edge of INT0-INT3
|
||||
EICRA &= EICRx_BIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Used by the sender to synchronize timing with the reciver.
|
||||
static void sync_recv(void) NO_INLINE;
|
||||
static
|
||||
void sync_recv(void) {
|
||||
for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) {
|
||||
}
|
||||
// This shouldn't hang if the target disconnects because the
|
||||
// serial line will float to high if the target does disconnect.
|
||||
while (!serial_read_pin());
|
||||
}
|
||||
|
||||
// Used by the reciver to send a synchronization signal to the sender.
|
||||
static void sync_send(void) NO_INLINE;
|
||||
static
|
||||
void sync_send(void) {
|
||||
serial_low();
|
||||
serial_delay();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
// Reads a byte from the serial line
|
||||
static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE;
|
||||
static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) {
|
||||
uint8_t byte, i, p, pb;
|
||||
|
||||
_delay_sub_us(READ_WRITE_START_ADJUST);
|
||||
for( i = 0, byte = 0, p = PARITY; i < bit; i++ ) {
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
if( serial_read_pin() ) {
|
||||
byte = (byte << 1) | 1; p ^= 1;
|
||||
} else {
|
||||
byte = (byte << 1) | 0; p ^= 0;
|
||||
}
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
}
|
||||
/* recive parity bit */
|
||||
serial_delay_half1(); // read the middle of pulses
|
||||
pb = serial_read_pin();
|
||||
_delay_sub_us(READ_WRITE_WIDTH_ADJUST);
|
||||
serial_delay_half2();
|
||||
|
||||
*pterrcount += (p != pb)? 1 : 0;
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Sends a byte with MSB ordering
|
||||
void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE;
|
||||
void serial_write_chunk(uint8_t data, uint8_t bit) {
|
||||
uint8_t b, p;
|
||||
for( p = PARITY, b = 1<<(bit-1); b ; b >>= 1) {
|
||||
if(data & b) {
|
||||
serial_high(); p ^= 1;
|
||||
} else {
|
||||
serial_low(); p ^= 0;
|
||||
}
|
||||
serial_delay();
|
||||
}
|
||||
/* send parity bit */
|
||||
if(p & 1) { serial_high(); }
|
||||
else { serial_low(); }
|
||||
serial_delay();
|
||||
|
||||
serial_low(); // sync_send() / senc_recv() need raise edge
|
||||
}
|
||||
|
||||
static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
|
||||
static
|
||||
void serial_send_packet(uint8_t *buffer, uint8_t size) {
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
data = buffer[i];
|
||||
sync_send();
|
||||
serial_write_chunk(data,8);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE;
|
||||
static
|
||||
uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) {
|
||||
uint8_t pecount = 0;
|
||||
for (uint8_t i = 0; i < size; ++i) {
|
||||
uint8_t data;
|
||||
sync_recv();
|
||||
data = serial_read_chunk(&pecount, 8);
|
||||
buffer[i] = data;
|
||||
}
|
||||
return pecount == 0;
|
||||
}
|
||||
|
||||
inline static
|
||||
void change_sender2reciver(void) {
|
||||
sync_send(); //0
|
||||
serial_delay_half1(); //1
|
||||
serial_low(); //2
|
||||
serial_input_with_pullup(); //2
|
||||
serial_delay_half1(); //3
|
||||
}
|
||||
|
||||
inline static
|
||||
void change_reciver2sender(void) {
|
||||
sync_recv(); //0
|
||||
serial_delay(); //1
|
||||
serial_low(); //3
|
||||
serial_output(); //3
|
||||
serial_delay_half1(); //4
|
||||
}
|
||||
|
||||
static inline uint8_t nibble_bits_count(uint8_t bits)
|
||||
{
|
||||
bits = (bits & 0x5) + (bits >> 1 & 0x5);
|
||||
bits = (bits & 0x3) + (bits >> 2 & 0x3);
|
||||
return bits;
|
||||
}
|
||||
|
||||
// interrupt handle to be used by the target device
|
||||
ISR(SERIAL_PIN_INTERRUPT) {
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
serial_low();
|
||||
serial_output();
|
||||
SSTD_t *trans = Transaction_table;
|
||||
#else
|
||||
// recive transaction table index
|
||||
uint8_t tid, bits;
|
||||
uint8_t pecount = 0;
|
||||
sync_recv();
|
||||
bits = serial_read_chunk(&pecount,7);
|
||||
tid = bits>>3;
|
||||
bits = (bits&7) != nibble_bits_count(tid);
|
||||
if( bits || pecount> 0 || tid > Transaction_table_size ) {
|
||||
return;
|
||||
}
|
||||
serial_delay_half1();
|
||||
|
||||
serial_high(); // response step1 low->high
|
||||
serial_output();
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH);
|
||||
SSTD_t *trans = &Transaction_table[tid];
|
||||
serial_low(); // response step2 ack high->low
|
||||
#endif
|
||||
|
||||
// target send phase
|
||||
if( trans->target2initiator_buffer_size > 0 )
|
||||
serial_send_packet((uint8_t *)trans->target2initiator_buffer,
|
||||
trans->target2initiator_buffer_size);
|
||||
// target switch to input
|
||||
change_sender2reciver();
|
||||
|
||||
// target recive phase
|
||||
if( trans->initiator2target_buffer_size > 0 ) {
|
||||
if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer,
|
||||
trans->initiator2target_buffer_size) ) {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
} else {
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
} else {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
}
|
||||
|
||||
sync_recv(); //weit initiator output to high
|
||||
}
|
||||
|
||||
/////////
|
||||
// start transaction by initiator
|
||||
//
|
||||
// int soft_serial_transaction(int sstd_index)
|
||||
//
|
||||
// Returns:
|
||||
// TRANSACTION_END
|
||||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
SSTD_t *trans = Transaction_table;
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
if( sstd_index > Transaction_table_size )
|
||||
return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
#endif
|
||||
cli();
|
||||
|
||||
// signal to the target that we want to start a transaction
|
||||
serial_output();
|
||||
serial_low();
|
||||
_delay_us(SLAVE_INT_WIDTH_US);
|
||||
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
// wait for the target response
|
||||
serial_input_with_pullup();
|
||||
_delay_us(SLAVE_INT_RESPONSE_TIME);
|
||||
|
||||
// check if the target is present
|
||||
if (serial_read_pin()) {
|
||||
// target failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
|
||||
#else
|
||||
// send transaction table index
|
||||
int tid = (sstd_index<<3) | (7 & nibble_bits_count(sstd_index));
|
||||
sync_send();
|
||||
_delay_sub_us(TID_SEND_ADJUST);
|
||||
serial_write_chunk(tid, 7);
|
||||
serial_delay_half1();
|
||||
|
||||
// wait for the target response (step1 low->high)
|
||||
serial_input_with_pullup();
|
||||
while( !serial_read_pin() ) {
|
||||
_delay_sub_us(2);
|
||||
}
|
||||
|
||||
// check if the target is present (step2 high->low)
|
||||
for( int i = 0; serial_read_pin(); i++ ) {
|
||||
if (i > SLAVE_INT_ACK_WIDTH + 1) {
|
||||
// slave failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
// initiator recive phase
|
||||
// if the target is present syncronize with it
|
||||
if( trans->target2initiator_buffer_size > 0 ) {
|
||||
if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer,
|
||||
trans->target2initiator_buffer_size) ) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
sei();
|
||||
return TRANSACTION_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// initiator switch to output
|
||||
change_reciver2sender();
|
||||
|
||||
// initiator send phase
|
||||
if( trans->initiator2target_buffer_size > 0 ) {
|
||||
serial_send_packet((uint8_t *)trans->initiator2target_buffer,
|
||||
trans->initiator2target_buffer_size);
|
||||
}
|
||||
|
||||
// always, release the line when not in use
|
||||
sync_send();
|
||||
|
||||
*trans->status = TRANSACTION_END;
|
||||
sei();
|
||||
return TRANSACTION_END;
|
||||
}
|
||||
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index) {
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
cli();
|
||||
int retval = *trans->status;
|
||||
*trans->status = 0;;
|
||||
sei();
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Helix serial.c history
|
||||
// 2018-1-29 fork from let's split and add PD2, modify sync_recv() (#2308, bceffdefc)
|
||||
// 2018-6-28 bug fix master to slave comm and speed up (#3255, 1038bbef4)
|
||||
// (adjusted with avr-gcc 4.9.2)
|
||||
// 2018-7-13 remove USE_SERIAL_PD2 macro (#3374, f30d6dd78)
|
||||
// (adjusted with avr-gcc 4.9.2)
|
||||
// 2018-8-11 add support multi-type transaction (#3608, feb5e4aae)
|
||||
// (adjusted with avr-gcc 4.9.2)
|
||||
// 2018-10-21 fix serial and RGB animation conflict (#4191, 4665e4fff)
|
||||
// (adjusted with avr-gcc 7.3.0)
|
||||
// 2018-10-28 re-adjust compiler depend value of delay (#4269, 8517f8a66)
|
||||
// (adjusted with avr-gcc 5.4.0, 7.3.0)
|
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Need Soft Serial defines in config.h
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// ex.
|
||||
// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
|
||||
// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
|
||||
// // 1: about 137kbps (default)
|
||||
// // 2: about 75kbps
|
||||
// // 3: about 39kbps
|
||||
// // 4: about 26kbps
|
||||
// // 5: about 20kbps
|
||||
//
|
||||
// //// USE OLD API (compatible with let's split serial.c)
|
||||
// ex.
|
||||
// #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
// #define SERIAL_MASTER_BUFFER_LENGTH 1
|
||||
//
|
||||
// //// USE NEW API
|
||||
// //// USE simple API (using signle-type transaction function)
|
||||
// #define SERIAL_USE_SINGLE_TRANSACTION
|
||||
// //// USE flexible API (using multi-type transaction function)
|
||||
// #define SERIAL_USE_MULTI_TRANSACTION
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////// for backward compatibility ////////////////////////////////
|
||||
#if !defined(SERIAL_USE_SINGLE_TRANSACTION) && !defined(SERIAL_USE_MULTI_TRANSACTION)
|
||||
/* --- USE OLD API (compatible with let's split serial.c) */
|
||||
#if SERIAL_SLAVE_BUFFER_LENGTH > 0
|
||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||
#endif
|
||||
#if SERIAL_MASTER_BUFFER_LENGTH > 0
|
||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||
#endif
|
||||
|
||||
void serial_master_init(void);
|
||||
void serial_slave_init(void);
|
||||
int serial_update_buffers(void);
|
||||
|
||||
#endif // end of USE OLD API
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Soft Serial Transaction Descriptor
|
||||
typedef struct _SSTD_t {
|
||||
uint8_t *status;
|
||||
uint8_t initiator2target_buffer_size;
|
||||
uint8_t *initiator2target_buffer;
|
||||
uint8_t target2initiator_buffer_size;
|
||||
uint8_t *target2initiator_buffer;
|
||||
} SSTD_t;
|
||||
#define TID_LIMIT( table ) (sizeof(table) / sizeof(SSTD_t))
|
||||
|
||||
// initiator is transaction start side
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
// target is interrupt accept side
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
|
||||
// initiator resullt
|
||||
#define TRANSACTION_END 0
|
||||
#define TRANSACTION_NO_RESPONSE 0x1
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void);
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
#endif
|
||||
|
||||
// target status
|
||||
// *SSTD_t.status has
|
||||
// initiator:
|
||||
// TRANSACTION_END
|
||||
// or TRANSACTION_NO_RESPONSE
|
||||
// or TRANSACTION_DATA_ERROR
|
||||
// target:
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// or TRANSACTION_ACCEPTED
|
||||
#define TRANSACTION_ACCEPTED 0x8
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
#endif
|
@ -0,0 +1,342 @@
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
#include "ssd1306.h"
|
||||
#include "i2c.h"
|
||||
#include <string.h>
|
||||
#include "print.h"
|
||||
#ifndef LOCAL_GLCDFONT
|
||||
#include "common/glcdfont.c"
|
||||
#else
|
||||
#include <helixfont.h>
|
||||
#endif
|
||||
#ifdef ADAFRUIT_BLE_ENABLE
|
||||
#include "adafruit_ble.h"
|
||||
#endif
|
||||
#ifdef PROTOCOL_LUFA
|
||||
#include "lufa.h"
|
||||
#endif
|
||||
#include "sendchar.h"
|
||||
#include "timer.h"
|
||||
|
||||
// Set this to 1 to help diagnose early startup problems
|
||||
// when testing power-on with ble. Turn it off otherwise,
|
||||
// as the latency of printing most of the debug info messes
|
||||
// with the matrix scan, causing keys to drop.
|
||||
#define DEBUG_TO_SCREEN 0
|
||||
|
||||
//static uint16_t last_battery_update;
|
||||
//static uint32_t vbat;
|
||||
//#define BatteryUpdateInterval 10000 /* milliseconds */
|
||||
|
||||
// 'last_flush' is declared as uint16_t,
|
||||
// so this must be less than 65535
|
||||
#define ScreenOffInterval 60000 /* milliseconds */
|
||||
#if DEBUG_TO_SCREEN
|
||||
static uint8_t displaying;
|
||||
#endif
|
||||
static uint16_t last_flush;
|
||||
|
||||
static bool force_dirty = true;
|
||||
|
||||
// Write command sequence.
|
||||
// Returns true on success.
|
||||
static inline bool _send_cmd1(uint8_t cmd) {
|
||||
bool res = false;
|
||||
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (i2c_master_write(0x0 /* command byte follows */)) {
|
||||
print("failed to write control byte\n");
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (i2c_master_write(cmd)) {
|
||||
xprintf("failed to write command %d\n", cmd);
|
||||
goto done;
|
||||
}
|
||||
res = true;
|
||||
done:
|
||||
i2c_master_stop();
|
||||
return res;
|
||||
}
|
||||
|
||||
// Write 2-byte command sequence.
|
||||
// Returns true on success
|
||||
static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
|
||||
if (!_send_cmd1(cmd)) {
|
||||
return false;
|
||||
}
|
||||
return _send_cmd1(opr);
|
||||
}
|
||||
|
||||
// Write 3-byte command sequence.
|
||||
// Returns true on success
|
||||
static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
|
||||
if (!_send_cmd1(cmd)) {
|
||||
return false;
|
||||
}
|
||||
if (!_send_cmd1(opr1)) {
|
||||
return false;
|
||||
}
|
||||
return _send_cmd1(opr2);
|
||||
}
|
||||
|
||||
#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
|
||||
#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
|
||||
#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
|
||||
|
||||
static void clear_display(void) {
|
||||
matrix_clear(&display);
|
||||
|
||||
// Clear all of the display bits (there can be random noise
|
||||
// in the RAM on startup)
|
||||
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
|
||||
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
|
||||
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
goto done;
|
||||
}
|
||||
if (i2c_master_write(0x40)) {
|
||||
// Data mode
|
||||
goto done;
|
||||
}
|
||||
for (uint8_t row = 0; row < MatrixRows; ++row) {
|
||||
for (uint8_t col = 0; col < DisplayWidth; ++col) {
|
||||
i2c_master_write(0);
|
||||
}
|
||||
}
|
||||
|
||||
display.dirty = false;
|
||||
|
||||
done:
|
||||
i2c_master_stop();
|
||||
}
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
#undef sendchar
|
||||
static int8_t capture_sendchar(uint8_t c) {
|
||||
sendchar(c);
|
||||
iota_gfx_write_char(c);
|
||||
|
||||
if (!displaying) {
|
||||
iota_gfx_flush();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool iota_gfx_init(bool rotate) {
|
||||
bool success = false;
|
||||
|
||||
i2c_master_init();
|
||||
send_cmd1(DisplayOff);
|
||||
send_cmd2(SetDisplayClockDiv, 0x80);
|
||||
send_cmd2(SetMultiPlex, DisplayHeight - 1);
|
||||
|
||||
send_cmd2(SetDisplayOffset, 0);
|
||||
|
||||
|
||||
send_cmd1(SetStartLine | 0x0);
|
||||
send_cmd2(SetChargePump, 0x14 /* Enable */);
|
||||
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
|
||||
|
||||
if(rotate){
|
||||
// the following Flip the display orientation 180 degrees
|
||||
send_cmd1(SegRemap);
|
||||
send_cmd1(ComScanInc);
|
||||
}else{
|
||||
// Flips the display orientation 0 degrees
|
||||
send_cmd1(SegRemap | 0x1);
|
||||
send_cmd1(ComScanDec);
|
||||
}
|
||||
|
||||
send_cmd2(SetComPins, 0x2);
|
||||
send_cmd2(SetContrast, 0x8f);
|
||||
send_cmd2(SetPreCharge, 0xf1);
|
||||
send_cmd2(SetVComDetect, 0x40);
|
||||
send_cmd1(DisplayAllOnResume);
|
||||
send_cmd1(NormalDisplay);
|
||||
send_cmd1(DeActivateScroll);
|
||||
send_cmd1(DisplayOn);
|
||||
|
||||
send_cmd2(SetContrast, 0); // Dim
|
||||
|
||||
clear_display();
|
||||
|
||||
success = true;
|
||||
|
||||
iota_gfx_flush();
|
||||
|
||||
#if DEBUG_TO_SCREEN
|
||||
print_set_sendchar(capture_sendchar);
|
||||
#endif
|
||||
|
||||
done:
|
||||
return success;
|
||||
}
|
||||
|
||||
bool iota_gfx_off(void) {
|
||||
bool success = false;
|
||||
|
||||
send_cmd1(DisplayOff);
|
||||
success = true;
|
||||
|
||||
done:
|
||||
return success;
|
||||
}
|
||||
|
||||
bool iota_gfx_on(void) {
|
||||
bool success = false;
|
||||
|
||||
send_cmd1(DisplayOn);
|
||||
success = true;
|
||||
|
||||
done:
|
||||
return success;
|
||||
}
|
||||
|
||||
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
|
||||
*matrix->cursor = c;
|
||||
++matrix->cursor;
|
||||
|
||||
if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
|
||||
// We went off the end; scroll the display upwards by one line
|
||||
memmove(&matrix->display[0], &matrix->display[1],
|
||||
MatrixCols * (MatrixRows - 1));
|
||||
matrix->cursor = &matrix->display[MatrixRows - 1][0];
|
||||
memset(matrix->cursor, ' ', MatrixCols);
|
||||
}
|
||||
}
|
||||
|
||||
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
|
||||
matrix->dirty = true;
|
||||
|
||||
if (c == '\n') {
|
||||
// Clear to end of line from the cursor and then move to the
|
||||
// start of the next line
|
||||
uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
|
||||
|
||||
while (cursor_col++ < MatrixCols) {
|
||||
matrix_write_char_inner(matrix, ' ');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
matrix_write_char_inner(matrix, c);
|
||||
}
|
||||
|
||||
void iota_gfx_write_char(uint8_t c) {
|
||||
matrix_write_char(&display, c);
|
||||
}
|
||||
|
||||
void matrix_write(struct CharacterMatrix *matrix, const char *data) {
|
||||
const char *end = data + strlen(data);
|
||||
while (data < end) {
|
||||
matrix_write_char(matrix, *data);
|
||||
++data;
|
||||
}
|
||||
}
|
||||
|
||||
void iota_gfx_write(const char *data) {
|
||||
matrix_write(&display, data);
|
||||
}
|
||||
|
||||
void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
|
||||
while (true) {
|
||||
uint8_t c = pgm_read_byte(data);
|
||||
if (c == 0) {
|
||||
return;
|
||||
}
|
||||
matrix_write_char(matrix, c);
|
||||
++data;
|
||||
}
|
||||
}
|
||||
|
||||
void iota_gfx_write_P(const char *data) {
|
||||
matrix_write_P(&display, data);
|
||||
}
|
||||
|
||||
void matrix_clear(struct CharacterMatrix *matrix) {
|
||||
memset(matrix->display, ' ', sizeof(matrix->display));
|
||||
matrix->cursor = &matrix->display[0][0];
|
||||
matrix->dirty = true;
|
||||
}
|
||||
|
||||
void iota_gfx_clear_screen(void) {
|
||||
matrix_clear(&display);
|
||||
}
|
||||
|
||||
void matrix_render(struct CharacterMatrix *matrix) {
|
||||
last_flush = timer_read();
|
||||
iota_gfx_on();
|
||||
#if DEBUG_TO_SCREEN
|
||||
++displaying;
|
||||
#endif
|
||||
|
||||
// Move to the home position
|
||||
send_cmd3(PageAddr, 0, MatrixRows - 1);
|
||||
send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
|
||||
|
||||
if (i2c_start_write(SSD1306_ADDRESS)) {
|
||||
goto done;
|
||||
}
|
||||
if (i2c_master_write(0x40)) {
|
||||
// Data mode
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (uint8_t row = 0; row < MatrixRows; ++row) {
|
||||
for (uint8_t col = 0; col < MatrixCols; ++col) {
|
||||
const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth);
|
||||
|
||||
for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) {
|
||||
uint8_t colBits = pgm_read_byte(glyph + glyphCol);
|
||||
i2c_master_write(colBits);
|
||||
}
|
||||
|
||||
// 1 column of space between chars (it's not included in the glyph)
|
||||
//i2c_master_write(0);
|
||||
}
|
||||
}
|
||||
|
||||
matrix->dirty = false;
|
||||
|
||||
done:
|
||||
i2c_master_stop();
|
||||
#if DEBUG_TO_SCREEN
|
||||
--displaying;
|
||||
#endif
|
||||
}
|
||||
|
||||
void iota_gfx_flush(void) {
|
||||
matrix_render(&display);
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void iota_gfx_task_user(void) {
|
||||
}
|
||||
|
||||
void iota_gfx_task(void) {
|
||||
iota_gfx_task_user();
|
||||
|
||||
if (display.dirty|| force_dirty) {
|
||||
iota_gfx_flush();
|
||||
force_dirty = false;
|
||||
}
|
||||
|
||||
if (timer_elapsed(last_flush) > ScreenOffInterval) {
|
||||
iota_gfx_off();
|
||||
}
|
||||
}
|
||||
|
||||
bool process_record_gfx(uint16_t keycode, keyrecord_t *record) {
|
||||
force_dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "pincontrol.h"
|
||||
#include "action.h"
|
||||
|
||||
enum ssd1306_cmds {
|
||||
DisplayOff = 0xAE,
|
||||
DisplayOn = 0xAF,
|
||||
|
||||
SetContrast = 0x81,
|
||||
DisplayAllOnResume = 0xA4,
|
||||
|
||||
DisplayAllOn = 0xA5,
|
||||
NormalDisplay = 0xA6,
|
||||
InvertDisplay = 0xA7,
|
||||
SetDisplayOffset = 0xD3,
|
||||
SetComPins = 0xda,
|
||||
SetVComDetect = 0xdb,
|
||||
SetDisplayClockDiv = 0xD5,
|
||||
SetPreCharge = 0xd9,
|
||||
SetMultiPlex = 0xa8,
|
||||
SetLowColumn = 0x00,
|
||||
SetHighColumn = 0x10,
|
||||
SetStartLine = 0x40,
|
||||
|
||||
SetMemoryMode = 0x20,
|
||||
ColumnAddr = 0x21,
|
||||
PageAddr = 0x22,
|
||||
|
||||
ComScanInc = 0xc0,
|
||||
ComScanDec = 0xc8,
|
||||
SegRemap = 0xa0,
|
||||
SetChargePump = 0x8d,
|
||||
ExternalVcc = 0x01,
|
||||
SwitchCapVcc = 0x02,
|
||||
|
||||
ActivateScroll = 0x2f,
|
||||
DeActivateScroll = 0x2e,
|
||||
SetVerticalScrollArea = 0xa3,
|
||||
RightHorizontalScroll = 0x26,
|
||||
LeftHorizontalScroll = 0x27,
|
||||
VerticalAndRightHorizontalScroll = 0x29,
|
||||
VerticalAndLeftHorizontalScroll = 0x2a,
|
||||
};
|
||||
|
||||
// Controls the SSD1306 128x32 OLED display via i2c
|
||||
|
||||
#ifndef SSD1306_ADDRESS
|
||||
#define SSD1306_ADDRESS 0x3C
|
||||
#endif
|
||||
|
||||
#define DisplayHeight 32
|
||||
#define DisplayWidth 128
|
||||
|
||||
#define FontHeight 8
|
||||
#define FontWidth 6
|
||||
|
||||
#define MatrixRows (DisplayHeight / FontHeight)
|
||||
#define MatrixCols (DisplayWidth / FontWidth)
|
||||
|
||||
struct CharacterMatrix {
|
||||
uint8_t display[MatrixRows][MatrixCols];
|
||||
uint8_t *cursor;
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
struct CharacterMatrix display;
|
||||
|
||||
bool iota_gfx_init(bool rotate);
|
||||
void iota_gfx_task(void);
|
||||
bool iota_gfx_off(void);
|
||||
bool iota_gfx_on(void);
|
||||
void iota_gfx_flush(void);
|
||||
void iota_gfx_write_char(uint8_t c);
|
||||
void iota_gfx_write(const char *data);
|
||||
void iota_gfx_write_P(const char *data);
|
||||
void iota_gfx_clear_screen(void);
|
||||
|
||||
void iota_gfx_task_user(void);
|
||||
|
||||
void matrix_clear(struct CharacterMatrix *matrix);
|
||||
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c);
|
||||
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c);
|
||||
void matrix_write(struct CharacterMatrix *matrix, const char *data);
|
||||
void matrix_write_P(struct CharacterMatrix *matrix, const char *data);
|
||||
void matrix_render(struct CharacterMatrix *matrix);
|
||||
|
||||
bool process_record_gfx(uint16_t keycode, keyrecord_t *record);
|
@ -0,0 +1 @@
|
||||
#include "treadstone48.h"
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef KEYBOARD_treadstone48_rev1
|
||||
#include "rev1.h"
|
||||
#endif
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#ifdef PROTOCOL_LUFA
|
||||
#include "lufa.h"
|
||||
#include "split_util.h"
|
||||
#endif
|
||||
#ifdef SSD1306OLED
|
||||
#include "ssd1306.h"
|
||||
#endif
|
@ -0,0 +1,2 @@
|
||||
BACKLIGHT_ENABLE = no
|
||||
RGBLIGHT_ENABLE = no
|
@ -1,4 +1,7 @@
|
||||
# A Colemak layout for XD75 with both Mac and Windows layers.
|
||||
# These two layers share momentary toggle access to a "Symbol" layer, which is modeled after my Planck layout.
|
||||
# Each of the base Colemak layers have their own Navigation layers for the right hand to use arrows and shortcuts for both text editing and web browsing.
|
||||
# The rules.mk file overrides the XD75's "BACKLIGHT_ENABLE" with YES and also adds tap dance functionality.
|
||||
# XD75
|
||||
|
||||
This is a Colemak layout for XD75 with both Mac and Windows layers.
|
||||
These two layers share momentary toggle access to a "Symbol" layer, which is modeled after my Planck layout (see planck/keymaps/davidrambo).
|
||||
Each of the base Colemak layers have their own Navigation layers for the right hand to use arrows and shortcuts for both text editing and web browsing.
|
||||
|
||||
The rules.mk file overrides the XD75's "BACKLIGHT_ENABLE" with YES and also adds tap dance functionality.
|
@ -0,0 +1,66 @@
|
||||
![layer0](https://i.imgur.com/vd4QLBf.png)
|
||||
|
||||
![layer1](https://i.imgur.com/eo101eD.png)
|
||||
|
||||
# BEPO keymap for the ErgoDox (alternate version)
|
||||
|
||||
This keymap has been made for the BEPO layout (https://bepo.fr), which is an ergonomic french keyboard layout based on Dvorak rules. As it's made for french people, the following of this readme will be in french.
|
||||
|
||||
Keyboard Maintainer: [Nicolas CARPi](https://github.com/NicolasCARPi)
|
||||
|
||||
Hardware Supported: Ergodox EZ
|
||||
|
||||
## Disposition BÉPO pour l'ErgoDox
|
||||
|
||||
Cette keymap a été adaptée de la keymap "bepo_csa" présente dans le dossier parent.
|
||||
|
||||
Certaines modifications ont été apportées pour ressembler un peu plus à une clavier traditionel:
|
||||
|
||||
* entrée sur la touche tout en bas à droite (comme la touche entrée du pavé numérique sur un clavier traditionnel)
|
||||
* plusieurs touches "Super" pour faciliter son accès
|
||||
|
||||
Il y a deux layers, celui de base, et celui avec les flèches, les touches fonction et la souris (main gauche).
|
||||
|
||||
## Particularités
|
||||
|
||||
* Touches de repos des pouces : "espace" à gauche et "entrée" à droite.
|
||||
* Touche Ctrl gauche accessible avec la paume de la main.
|
||||
* Touche "w" placée sur la main gauche (j'ai toujours trouvé le "w" difficle d'accès sur un clavier bépo classique.
|
||||
* Plusieurs touches F12.
|
||||
* Les flèches sont disposées avec un déplacement à la VIM.
|
||||
* Un mode souris permet d'utiliser la souris avec le clavier.
|
||||
* Possibilité de changer de mode de manière temporaire ou permanente.
|
||||
* Les leds s'allument avec SHIFT, ALT ou la touche function.
|
||||
|
||||
J'ai fait cette disposition pour mes besoins, à vous de la modifier pour les vôtres ;)
|
||||
|
||||
## Utilisation
|
||||
|
||||
### Pré-requis
|
||||
|
||||
Pour Archlinux, il est nécessaire d'installer ces paquets au préalable:
|
||||
|
||||
~~~bash
|
||||
sudo pacman -S avr-gcc avr-libc teensy-loader-cli
|
||||
~~~
|
||||
|
||||
Les paquets "avr" permettent de compiler le firmware, et teensy-loader permet de le charger sur le clavier.
|
||||
|
||||
### Compilation
|
||||
|
||||
~~~bash
|
||||
# clone the repo
|
||||
git clone https://github.com/qmk/qmk_firmware
|
||||
# install submodules
|
||||
make git-submodule
|
||||
# compile this layout
|
||||
make ergodox_ez:bepo_alt
|
||||
~~~
|
||||
|
||||
### Chargement
|
||||
|
||||
~~~bash
|
||||
teensy-loader-cli -w -mmcu=atmega32u4 -v ergodox_ez_bepo_alt.hex && sleep 6 && setxkbmap fr bepo
|
||||
~~~
|
||||
|
||||
J'ai ajouté un sleep avant la commande pour remettre en bépo afin de laisser au clavier le temps de rebooter.
|
@ -0,0 +1,5 @@
|
||||
# Having a file like this allows you to override Makefile definitions
|
||||
# for your own particular keymap
|
||||
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 FastLED
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,242 @@
|
||||
#define FASTLED_INTERNAL
|
||||
#include <stdint.h>
|
||||
|
||||
#define RAND16_SEED 1337
|
||||
uint16_t rand16seed = RAND16_SEED;
|
||||
|
||||
|
||||
// memset8, memcpy8, memmove8:
|
||||
// optimized avr replacements for the standard "C" library
|
||||
// routines memset, memcpy, and memmove.
|
||||
//
|
||||
// There are two techniques that make these routines
|
||||
// faster than the standard avr-libc routines.
|
||||
// First, the loops are unrolled 2X, meaning that
|
||||
// the average loop overhead is cut in half.
|
||||
// And second, the compare-and-branch at the bottom
|
||||
// of each loop decrements the low byte of the
|
||||
// counter, and if the carry is clear, it branches
|
||||
// back up immediately. Only if the low byte math
|
||||
// causes carry do we bother to decrement the high
|
||||
// byte and check that result for carry as well.
|
||||
// Results for a 100-byte buffer are 20-40% faster
|
||||
// than standard avr-libc, at a cost of a few extra
|
||||
// bytes of code.
|
||||
|
||||
#if defined(__AVR__)
|
||||
//__attribute__ ((noinline))
|
||||
void * memset8 ( void * ptr, uint8_t val, uint16_t num )
|
||||
{
|
||||
asm volatile(
|
||||
" movw r26, %[ptr] \n\t"
|
||||
" sbrs %A[num], 0 \n\t"
|
||||
" rjmp Lseteven_%= \n\t"
|
||||
" rjmp Lsetodd_%= \n\t"
|
||||
"Lsetloop_%=: \n\t"
|
||||
" st X+, %[val] \n\t"
|
||||
"Lsetodd_%=: \n\t"
|
||||
" st X+, %[val] \n\t"
|
||||
"Lseteven_%=: \n\t"
|
||||
" subi %A[num], 2 \n\t"
|
||||
" brcc Lsetloop_%= \n\t"
|
||||
" sbci %B[num], 0 \n\t"
|
||||
" brcc Lsetloop_%= \n\t"
|
||||
: [num] "+r" (num)
|
||||
: [ptr] "r" (ptr),
|
||||
[val] "r" (val)
|
||||
: "memory"
|
||||
);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//__attribute__ ((noinline))
|
||||
void * memcpy8 ( void * dst, const void* src, uint16_t num )
|
||||
{
|
||||
asm volatile(
|
||||
" movw r30, %[src] \n\t"
|
||||
" movw r26, %[dst] \n\t"
|
||||
" sbrs %A[num], 0 \n\t"
|
||||
" rjmp Lcpyeven_%= \n\t"
|
||||
" rjmp Lcpyodd_%= \n\t"
|
||||
"Lcpyloop_%=: \n\t"
|
||||
" ld __tmp_reg__, Z+ \n\t"
|
||||
" st X+, __tmp_reg__ \n\t"
|
||||
"Lcpyodd_%=: \n\t"
|
||||
" ld __tmp_reg__, Z+ \n\t"
|
||||
" st X+, __tmp_reg__ \n\t"
|
||||
"Lcpyeven_%=: \n\t"
|
||||
" subi %A[num], 2 \n\t"
|
||||
" brcc Lcpyloop_%= \n\t"
|
||||
" sbci %B[num], 0 \n\t"
|
||||
" brcc Lcpyloop_%= \n\t"
|
||||
: [num] "+r" (num)
|
||||
: [src] "r" (src),
|
||||
[dst] "r" (dst)
|
||||
: "memory"
|
||||
);
|
||||
return dst;
|
||||
}
|
||||
|
||||
//__attribute__ ((noinline))
|
||||
void * memmove8 ( void * dst, const void* src, uint16_t num )
|
||||
{
|
||||
if( src > dst) {
|
||||
// if src > dst then we can use the forward-stepping memcpy8
|
||||
return memcpy8( dst, src, num);
|
||||
} else {
|
||||
// if src < dst then we have to step backward:
|
||||
dst = (char*)dst + num;
|
||||
src = (char*)src + num;
|
||||
asm volatile(
|
||||
" movw r30, %[src] \n\t"
|
||||
" movw r26, %[dst] \n\t"
|
||||
" sbrs %A[num], 0 \n\t"
|
||||
" rjmp Lmoveven_%= \n\t"
|
||||
" rjmp Lmovodd_%= \n\t"
|
||||
"Lmovloop_%=: \n\t"
|
||||
" ld __tmp_reg__, -Z \n\t"
|
||||
" st -X, __tmp_reg__ \n\t"
|
||||
"Lmovodd_%=: \n\t"
|
||||
" ld __tmp_reg__, -Z \n\t"
|
||||
" st -X, __tmp_reg__ \n\t"
|
||||
"Lmoveven_%=: \n\t"
|
||||
" subi %A[num], 2 \n\t"
|
||||
" brcc Lmovloop_%= \n\t"
|
||||
" sbci %B[num], 0 \n\t"
|
||||
" brcc Lmovloop_%= \n\t"
|
||||
: [num] "+r" (num)
|
||||
: [src] "r" (src),
|
||||
[dst] "r" (dst)
|
||||
: "memory"
|
||||
);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AVR */
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
// TEST / VERIFICATION CODE ONLY BELOW THIS POINT
|
||||
#include <Arduino.h>
|
||||
#include "lib8tion.h"
|
||||
|
||||
void test1abs( int8_t i)
|
||||
{
|
||||
Serial.print("abs("); Serial.print(i); Serial.print(") = ");
|
||||
int8_t j = abs8(i);
|
||||
Serial.print(j); Serial.println(" ");
|
||||
}
|
||||
|
||||
void testabs()
|
||||
{
|
||||
delay(5000);
|
||||
for( int8_t q = -128; q != 127; q++) {
|
||||
test1abs(q);
|
||||
}
|
||||
for(;;){};
|
||||
}
|
||||
|
||||
|
||||
void testmul8()
|
||||
{
|
||||
delay(5000);
|
||||
byte r, c;
|
||||
|
||||
Serial.println("mul8:");
|
||||
for( r = 0; r <= 20; r += 1) {
|
||||
Serial.print(r); Serial.print(" : ");
|
||||
for( c = 0; c <= 20; c += 1) {
|
||||
byte t;
|
||||
t = mul8( r, c);
|
||||
Serial.print(t); Serial.print(' ');
|
||||
}
|
||||
Serial.println(' ');
|
||||
}
|
||||
Serial.println("done.");
|
||||
for(;;){};
|
||||
}
|
||||
|
||||
|
||||
void testscale8()
|
||||
{
|
||||
delay(5000);
|
||||
byte r, c;
|
||||
|
||||
Serial.println("scale8:");
|
||||
for( r = 0; r <= 240; r += 10) {
|
||||
Serial.print(r); Serial.print(" : ");
|
||||
for( c = 0; c <= 240; c += 10) {
|
||||
byte t;
|
||||
t = scale8( r, c);
|
||||
Serial.print(t); Serial.print(' ');
|
||||
}
|
||||
Serial.println(' ');
|
||||
}
|
||||
|
||||
Serial.println(' ');
|
||||
Serial.println("scale8_video:");
|
||||
|
||||
for( r = 0; r <= 100; r += 4) {
|
||||
Serial.print(r); Serial.print(" : ");
|
||||
for( c = 0; c <= 100; c += 4) {
|
||||
byte t;
|
||||
t = scale8_video( r, c);
|
||||
Serial.print(t); Serial.print(' ');
|
||||
}
|
||||
Serial.println(' ');
|
||||
}
|
||||
|
||||
Serial.println("done.");
|
||||
for(;;){};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void testqadd8()
|
||||
{
|
||||
delay(5000);
|
||||
byte r, c;
|
||||
for( r = 0; r <= 240; r += 10) {
|
||||
Serial.print(r); Serial.print(" : ");
|
||||
for( c = 0; c <= 240; c += 10) {
|
||||
byte t;
|
||||
t = qadd8( r, c);
|
||||
Serial.print(t); Serial.print(' ');
|
||||
}
|
||||
Serial.println(' ');
|
||||
}
|
||||
Serial.println("done.");
|
||||
for(;;){};
|
||||
}
|
||||
|
||||
void testnscale8x3()
|
||||
{
|
||||
delay(5000);
|
||||
byte r, g, b, sc;
|
||||
for( byte z = 0; z < 10; z++) {
|
||||
r = random8(); g = random8(); b = random8(); sc = random8();
|
||||
|
||||
Serial.print("nscale8x3_video( ");
|
||||
Serial.print(r); Serial.print(", ");
|
||||
Serial.print(g); Serial.print(", ");
|
||||
Serial.print(b); Serial.print(", ");
|
||||
Serial.print(sc); Serial.print(") = [ ");
|
||||
|
||||
nscale8x3_video( r, g, b, sc);
|
||||
|
||||
Serial.print(r); Serial.print(", ");
|
||||
Serial.print(g); Serial.print(", ");
|
||||
Serial.print(b); Serial.print("]");
|
||||
|
||||
Serial.println(' ');
|
||||
}
|
||||
Serial.println("done.");
|
||||
for(;;){};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,934 @@
|
||||
#ifndef __INC_LIB8TION_H
|
||||
#define __INC_LIB8TION_H
|
||||
|
||||
/*
|
||||
|
||||
Fast, efficient 8-bit math functions specifically
|
||||
designed for high-performance LED programming.
|
||||
|
||||
Because of the AVR(Arduino) and ARM assembly language
|
||||
implementations provided, using these functions often
|
||||
results in smaller and faster code than the equivalent
|
||||
program using plain "C" arithmetic and logic.
|
||||
|
||||
|
||||
Included are:
|
||||
|
||||
|
||||
- Saturating unsigned 8-bit add and subtract.
|
||||
Instead of wrapping around if an overflow occurs,
|
||||
these routines just 'clamp' the output at a maxumum
|
||||
of 255, or a minimum of 0. Useful for adding pixel
|
||||
values. E.g., qadd8( 200, 100) = 255.
|
||||
|
||||
qadd8( i, j) == MIN( (i + j), 0xFF )
|
||||
qsub8( i, j) == MAX( (i - j), 0 )
|
||||
|
||||
- Saturating signed 8-bit ("7-bit") add.
|
||||
qadd7( i, j) == MIN( (i + j), 0x7F)
|
||||
|
||||
|
||||
- Scaling (down) of unsigned 8- and 16- bit values.
|
||||
Scaledown value is specified in 1/256ths.
|
||||
scale8( i, sc) == (i * sc) / 256
|
||||
scale16by8( i, sc) == (i * sc) / 256
|
||||
|
||||
Example: scaling a 0-255 value down into a
|
||||
range from 0-99:
|
||||
downscaled = scale8( originalnumber, 100);
|
||||
|
||||
A special version of scale8 is provided for scaling
|
||||
LED brightness values, to make sure that they don't
|
||||
accidentally scale down to total black at low
|
||||
dimming levels, since that would look wrong:
|
||||
scale8_video( i, sc) = ((i * sc) / 256) +? 1
|
||||
|
||||
Example: reducing an LED brightness by a
|
||||
dimming factor:
|
||||
new_bright = scale8_video( orig_bright, dimming);
|
||||
|
||||
|
||||
- Fast 8- and 16- bit unsigned random numbers.
|
||||
Significantly faster than Arduino random(), but
|
||||
also somewhat less random. You can add entropy.
|
||||
random8() == random from 0..255
|
||||
random8( n) == random from 0..(N-1)
|
||||
random8( n, m) == random from N..(M-1)
|
||||
|
||||
random16() == random from 0..65535
|
||||
random16( n) == random from 0..(N-1)
|
||||
random16( n, m) == random from N..(M-1)
|
||||
|
||||
random16_set_seed( k) == seed = k
|
||||
random16_add_entropy( k) == seed += k
|
||||
|
||||
|
||||
- Absolute value of a signed 8-bit value.
|
||||
abs8( i) == abs( i)
|
||||
|
||||
|
||||
- 8-bit math operations which return 8-bit values.
|
||||
These are provided mostly for completeness,
|
||||
not particularly for performance.
|
||||
mul8( i, j) == (i * j) & 0xFF
|
||||
add8( i, j) == (i + j) & 0xFF
|
||||
sub8( i, j) == (i - j) & 0xFF
|
||||
|
||||
|
||||
- Fast 16-bit approximations of sin and cos.
|
||||
Input angle is a uint16_t from 0-65535.
|
||||
Output is a signed int16_t from -32767 to 32767.
|
||||
sin16( x) == sin( (x/32768.0) * pi) * 32767
|
||||
cos16( x) == cos( (x/32768.0) * pi) * 32767
|
||||
Accurate to more than 99% in all cases.
|
||||
|
||||
- Fast 8-bit approximations of sin and cos.
|
||||
Input angle is a uint8_t from 0-255.
|
||||
Output is an UNsigned uint8_t from 0 to 255.
|
||||
sin8( x) == (sin( (x/128.0) * pi) * 128) + 128
|
||||
cos8( x) == (cos( (x/128.0) * pi) * 128) + 128
|
||||
Accurate to within about 2%.
|
||||
|
||||
|
||||
- Fast 8-bit "easing in/out" function.
|
||||
ease8InOutCubic(x) == 3(x^i) - 2(x^3)
|
||||
ease8InOutApprox(x) ==
|
||||
faster, rougher, approximation of cubic easing
|
||||
ease8InOutQuad(x) == quadratic (vs cubic) easing
|
||||
|
||||
- Cubic, Quadratic, and Triangle wave functions.
|
||||
Input is a uint8_t representing phase withing the wave,
|
||||
similar to how sin8 takes an angle 'theta'.
|
||||
Output is a uint8_t representing the amplitude of
|
||||
the wave at that point.
|
||||
cubicwave8( x)
|
||||
quadwave8( x)
|
||||
triwave8( x)
|
||||
|
||||
- Square root for 16-bit integers. About three times
|
||||
faster and five times smaller than Arduino's built-in
|
||||
generic 32-bit sqrt routine.
|
||||
sqrt16( uint16_t x ) == sqrt( x)
|
||||
|
||||
- Dimming and brightening functions for 8-bit
|
||||
light values.
|
||||
dim8_video( x) == scale8_video( x, x)
|
||||
dim8_raw( x) == scale8( x, x)
|
||||
dim8_lin( x) == (x<128) ? ((x+1)/2) : scale8(x,x)
|
||||
brighten8_video( x) == 255 - dim8_video( 255 - x)
|
||||
brighten8_raw( x) == 255 - dim8_raw( 255 - x)
|
||||
brighten8_lin( x) == 255 - dim8_lin( 255 - x)
|
||||
The dimming functions in particular are suitable
|
||||
for making LED light output appear more 'linear'.
|
||||
|
||||
|
||||
- Linear interpolation between two values, with the
|
||||
fraction between them expressed as an 8- or 16-bit
|
||||
fixed point fraction (fract8 or fract16).
|
||||
lerp8by8( fromU8, toU8, fract8 )
|
||||
lerp16by8( fromU16, toU16, fract8 )
|
||||
lerp15by8( fromS16, toS16, fract8 )
|
||||
== from + (( to - from ) * fract8) / 256)
|
||||
lerp16by16( fromU16, toU16, fract16 )
|
||||
== from + (( to - from ) * fract16) / 65536)
|
||||
map8( in, rangeStart, rangeEnd)
|
||||
== map( in, 0, 255, rangeStart, rangeEnd);
|
||||
|
||||
- Optimized memmove, memcpy, and memset, that are
|
||||
faster than standard avr-libc 1.8.
|
||||
memmove8( dest, src, bytecount)
|
||||
memcpy8( dest, src, bytecount)
|
||||
memset8( buf, value, bytecount)
|
||||
|
||||
- Beat generators which return sine or sawtooth
|
||||
waves in a specified number of Beats Per Minute.
|
||||
Sine wave beat generators can specify a low and
|
||||
high range for the output. Sawtooth wave beat
|
||||
generators always range 0-255 or 0-65535.
|
||||
beatsin8( BPM, low8, high8)
|
||||
= (sine(beatphase) * (high8-low8)) + low8
|
||||
beatsin16( BPM, low16, high16)
|
||||
= (sine(beatphase) * (high16-low16)) + low16
|
||||
beatsin88( BPM88, low16, high16)
|
||||
= (sine(beatphase) * (high16-low16)) + low16
|
||||
beat8( BPM) = 8-bit repeating sawtooth wave
|
||||
beat16( BPM) = 16-bit repeating sawtooth wave
|
||||
beat88( BPM88) = 16-bit repeating sawtooth wave
|
||||
BPM is beats per minute in either simple form
|
||||
e.g. 120, or Q8.8 fixed-point form.
|
||||
BPM88 is beats per minute in ONLY Q8.8 fixed-point
|
||||
form.
|
||||
|
||||
Lib8tion is pronounced like 'libation': lie-BAY-shun
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define LIB8STATIC __attribute__ ((unused)) static inline
|
||||
#define LIB8STATIC_ALWAYS_INLINE __attribute__ ((always_inline)) static inline
|
||||
|
||||
#if !defined(__AVR__)
|
||||
#include <string.h>
|
||||
// for memmove, memcpy, and memset if not defined here
|
||||
#endif
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
#if defined(FASTLED_TEENSY3)
|
||||
// Can use Cortex M4 DSP instructions
|
||||
#define QADD8_C 0
|
||||
#define QADD7_C 0
|
||||
#define QADD8_ARM_DSP_ASM 1
|
||||
#define QADD7_ARM_DSP_ASM 1
|
||||
#else
|
||||
// Generic ARM
|
||||
#define QADD8_C 1
|
||||
#define QADD7_C 1
|
||||
#endif
|
||||
|
||||
#define QSUB8_C 1
|
||||
#define SCALE8_C 1
|
||||
#define SCALE16BY8_C 1
|
||||
#define SCALE16_C 1
|
||||
#define ABS8_C 1
|
||||
#define MUL8_C 1
|
||||
#define QMUL8_C 1
|
||||
#define ADD8_C 1
|
||||
#define SUB8_C 1
|
||||
#define EASE8_C 1
|
||||
#define AVG8_C 1
|
||||
#define AVG7_C 1
|
||||
#define AVG16_C 1
|
||||
#define AVG15_C 1
|
||||
#define BLEND8_C 1
|
||||
|
||||
|
||||
#elif defined(__AVR__)
|
||||
|
||||
// AVR ATmega and friends Arduino
|
||||
|
||||
#define QADD8_C 0
|
||||
#define QADD7_C 0
|
||||
#define QSUB8_C 0
|
||||
#define ABS8_C 0
|
||||
#define ADD8_C 0
|
||||
#define SUB8_C 0
|
||||
#define AVG8_C 0
|
||||
#define AVG7_C 0
|
||||
#define AVG16_C 0
|
||||
#define AVG15_C 0
|
||||
|
||||
#define QADD8_AVRASM 1
|
||||
#define QADD7_AVRASM 1
|
||||
#define QSUB8_AVRASM 1
|
||||
#define ABS8_AVRASM 1
|
||||
#define ADD8_AVRASM 1
|
||||
#define SUB8_AVRASM 1
|
||||
#define AVG8_AVRASM 1
|
||||
#define AVG7_AVRASM 1
|
||||
#define AVG16_AVRASM 1
|
||||
#define AVG15_AVRASM 1
|
||||
|
||||
// Note: these require hardware MUL instruction
|
||||
// -- sorry, ATtiny!
|
||||
#if !defined(LIB8_ATTINY)
|
||||
#define SCALE8_C 0
|
||||
#define SCALE16BY8_C 0
|
||||
#define SCALE16_C 0
|
||||
#define MUL8_C 0
|
||||
#define QMUL8_C 0
|
||||
#define EASE8_C 0
|
||||
#define BLEND8_C 0
|
||||
#define SCALE8_AVRASM 1
|
||||
#define SCALE16BY8_AVRASM 1
|
||||
#define SCALE16_AVRASM 1
|
||||
#define MUL8_AVRASM 1
|
||||
#define QMUL8_AVRASM 1
|
||||
#define EASE8_AVRASM 1
|
||||
#define CLEANUP_R1_AVRASM 1
|
||||
#define BLEND8_AVRASM 1
|
||||
#else
|
||||
// On ATtiny, we just use C implementations
|
||||
#define SCALE8_C 1
|
||||
#define SCALE16BY8_C 1
|
||||
#define SCALE16_C 1
|
||||
#define MUL8_C 1
|
||||
#define QMUL8_C 1
|
||||
#define EASE8_C 1
|
||||
#define BLEND8_C 1
|
||||
#define SCALE8_AVRASM 0
|
||||
#define SCALE16BY8_AVRASM 0
|
||||
#define SCALE16_AVRASM 0
|
||||
#define MUL8_AVRASM 0
|
||||
#define QMUL8_AVRASM 0
|
||||
#define EASE8_AVRASM 0
|
||||
#define BLEND8_AVRASM 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// unspecified architecture, so
|
||||
// no ASM, everything in C
|
||||
#define QADD8_C 1
|
||||
#define QADD7_C 1
|
||||
#define QSUB8_C 1
|
||||
#define SCALE8_C 1
|
||||
#define SCALE16BY8_C 1
|
||||
#define SCALE16_C 1
|
||||
#define ABS8_C 1
|
||||
#define MUL8_C 1
|
||||
#define QMUL8_C 1
|
||||
#define ADD8_C 1
|
||||
#define SUB8_C 1
|
||||
#define EASE8_C 1
|
||||
#define AVG8_C 1
|
||||
#define AVG7_C 1
|
||||
#define AVG16_C 1
|
||||
#define AVG15_C 1
|
||||
#define BLEND8_C 1
|
||||
|
||||
#endif
|
||||
|
||||
///@defgroup lib8tion Fast math functions
|
||||
///A variety of functions for working with numbers.
|
||||
///@{
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// typdefs for fixed-point fractional types.
|
||||
//
|
||||
// sfract7 should be interpreted as signed 128ths.
|
||||
// fract8 should be interpreted as unsigned 256ths.
|
||||
// sfract15 should be interpreted as signed 32768ths.
|
||||
// fract16 should be interpreted as unsigned 65536ths.
|
||||
//
|
||||
// Example: if a fract8 has the value "64", that should be interpreted
|
||||
// as 64/256ths, or one-quarter.
|
||||
//
|
||||
//
|
||||
// fract8 range is 0 to 0.99609375
|
||||
// in steps of 0.00390625
|
||||
//
|
||||
// sfract7 range is -0.9921875 to 0.9921875
|
||||
// in steps of 0.0078125
|
||||
//
|
||||
// fract16 range is 0 to 0.99998474121
|
||||
// in steps of 0.00001525878
|
||||
//
|
||||
// sfract15 range is -0.99996948242 to 0.99996948242
|
||||
// in steps of 0.00003051757
|
||||
//
|
||||
|
||||
/// ANSI unsigned short _Fract. range is 0 to 0.99609375
|
||||
/// in steps of 0.00390625
|
||||
typedef uint8_t fract8; ///< ANSI: unsigned short _Fract
|
||||
|
||||
/// ANSI: signed short _Fract. range is -0.9921875 to 0.9921875
|
||||
/// in steps of 0.0078125
|
||||
typedef int8_t sfract7; ///< ANSI: signed short _Fract
|
||||
|
||||
/// ANSI: unsigned _Fract. range is 0 to 0.99998474121
|
||||
/// in steps of 0.00001525878
|
||||
typedef uint16_t fract16; ///< ANSI: unsigned _Fract
|
||||
|
||||
/// ANSI: signed _Fract. range is -0.99996948242 to 0.99996948242
|
||||
/// in steps of 0.00003051757
|
||||
typedef int16_t sfract15; ///< ANSI: signed _Fract
|
||||
|
||||
|
||||
// accumXY types should be interpreted as X bits of integer,
|
||||
// and Y bits of fraction.
|
||||
// E.g., accum88 has 8 bits of int, 8 bits of fraction
|
||||
|
||||
typedef uint16_t accum88; ///< ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction
|
||||
typedef int16_t saccum78; ///< ANSI: signed short _Accum. 7 bits int, 8 bits fraction
|
||||
typedef uint32_t accum1616;///< ANSI: signed _Accum. 16 bits int, 16 bits fraction
|
||||
typedef int32_t saccum1516;///< ANSI: signed _Accum. 15 bits int, 16 bits fraction
|
||||
typedef uint16_t accum124; ///< no direct ANSI counterpart. 12 bits int, 4 bits fraction
|
||||
typedef int32_t saccum114;///< no direct ANSI counterpart. 1 bit int, 14 bits fraction
|
||||
|
||||
|
||||
|
||||
#include "math8.h"
|
||||
#include "scale8.h"
|
||||
#include "random8.h"
|
||||
#include "trig8.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// float-to-fixed and fixed-to-float conversions
|
||||
//
|
||||
// Note that anything involving a 'float' on AVR will be slower.
|
||||
|
||||
/// sfract15ToFloat: conversion from sfract15 fixed point to
|
||||
/// IEEE754 32-bit float.
|
||||
LIB8STATIC float sfract15ToFloat( sfract15 y)
|
||||
{
|
||||
return y / 32768.0;
|
||||
}
|
||||
|
||||
/// conversion from IEEE754 float in the range (-1,1)
|
||||
/// to 16-bit fixed point. Note that the extremes of
|
||||
/// one and negative one are NOT representable. The
|
||||
/// representable range is basically
|
||||
LIB8STATIC sfract15 floatToSfract15( float f)
|
||||
{
|
||||
return f * 32768.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// memmove8, memcpy8, and memset8:
|
||||
// alternatives to memmove, memcpy, and memset that are
|
||||
// faster on AVR than standard avr-libc 1.8
|
||||
|
||||
#if defined(__AVR__)
|
||||
void * memmove8( void * dst, const void * src, uint16_t num );
|
||||
void * memcpy8 ( void * dst, const void * src, uint16_t num ) __attribute__ ((noinline));
|
||||
void * memset8 ( void * ptr, uint8_t value, uint16_t num ) __attribute__ ((noinline)) ;
|
||||
#else
|
||||
// on non-AVR platforms, these names just call standard libc.
|
||||
#define memmove8 memmove
|
||||
#define memcpy8 memcpy
|
||||
#define memset8 memset
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// linear interpolation, such as could be used for Perlin noise, etc.
|
||||
//
|
||||
|
||||
// A note on the structure of the lerp functions:
|
||||
// The cases for b>a and b<=a are handled separately for
|
||||
// speed: without knowing the relative order of a and b,
|
||||
// the value (a-b) might be overflow the width of a or b,
|
||||
// and have to be promoted to a wider, slower type.
|
||||
// To avoid that, we separate the two cases, and are able
|
||||
// to do all the math in the same width as the arguments,
|
||||
// which is much faster and smaller on AVR.
|
||||
|
||||
/// linear interpolation between two unsigned 8-bit values,
|
||||
/// with 8-bit fraction
|
||||
LIB8STATIC uint8_t lerp8by8( uint8_t a, uint8_t b, fract8 frac)
|
||||
{
|
||||
uint8_t result;
|
||||
if( b > a) {
|
||||
uint8_t delta = b - a;
|
||||
uint8_t scaled = scale8( delta, frac);
|
||||
result = a + scaled;
|
||||
} else {
|
||||
uint8_t delta = a - b;
|
||||
uint8_t scaled = scale8( delta, frac);
|
||||
result = a - scaled;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// linear interpolation between two unsigned 16-bit values,
|
||||
/// with 16-bit fraction
|
||||
LIB8STATIC uint16_t lerp16by16( uint16_t a, uint16_t b, fract16 frac)
|
||||
{
|
||||
uint16_t result;
|
||||
if( b > a ) {
|
||||
uint16_t delta = b - a;
|
||||
uint16_t scaled = scale16(delta, frac);
|
||||
result = a + scaled;
|
||||
} else {
|
||||
uint16_t delta = a - b;
|
||||
uint16_t scaled = scale16( delta, frac);
|
||||
result = a - scaled;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// linear interpolation between two unsigned 16-bit values,
|
||||
/// with 8-bit fraction
|
||||
LIB8STATIC uint16_t lerp16by8( uint16_t a, uint16_t b, fract8 frac)
|
||||
{
|
||||
uint16_t result;
|
||||
if( b > a) {
|
||||
uint16_t delta = b - a;
|
||||
uint16_t scaled = scale16by8( delta, frac);
|
||||
result = a + scaled;
|
||||
} else {
|
||||
uint16_t delta = a - b;
|
||||
uint16_t scaled = scale16by8( delta, frac);
|
||||
result = a - scaled;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// linear interpolation between two signed 15-bit values,
|
||||
/// with 8-bit fraction
|
||||
LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac)
|
||||
{
|
||||
int16_t result;
|
||||
if( b > a) {
|
||||
uint16_t delta = b - a;
|
||||
uint16_t scaled = scale16by8( delta, frac);
|
||||
result = a + scaled;
|
||||
} else {
|
||||
uint16_t delta = a - b;
|
||||
uint16_t scaled = scale16by8( delta, frac);
|
||||
result = a - scaled;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// linear interpolation between two signed 15-bit values,
|
||||
/// with 8-bit fraction
|
||||
LIB8STATIC int16_t lerp15by16( int16_t a, int16_t b, fract16 frac)
|
||||
{
|
||||
int16_t result;
|
||||
if( b > a) {
|
||||
uint16_t delta = b - a;
|
||||
uint16_t scaled = scale16( delta, frac);
|
||||
result = a + scaled;
|
||||
} else {
|
||||
uint16_t delta = a - b;
|
||||
uint16_t scaled = scale16( delta, frac);
|
||||
result = a - scaled;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// map8: map from one full-range 8-bit value into a narrower
|
||||
/// range of 8-bit values, possibly a range of hues.
|
||||
///
|
||||
/// E.g. map myValue into a hue in the range blue..purple..pink..red
|
||||
/// hue = map8( myValue, HUE_BLUE, HUE_RED);
|
||||
///
|
||||
/// Combines nicely with the waveform functions (like sin8, etc)
|
||||
/// to produce continuous hue gradients back and forth:
|
||||
///
|
||||
/// hue = map8( sin8( myValue), HUE_BLUE, HUE_RED);
|
||||
///
|
||||
/// Mathematically simiar to lerp8by8, but arguments are more
|
||||
/// like Arduino's "map"; this function is similar to
|
||||
///
|
||||
/// map( in, 0, 255, rangeStart, rangeEnd)
|
||||
///
|
||||
/// but faster and specifically designed for 8-bit values.
|
||||
LIB8STATIC uint8_t map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
|
||||
{
|
||||
uint8_t rangeWidth = rangeEnd - rangeStart;
|
||||
uint8_t out = scale8( in, rangeWidth);
|
||||
out += rangeStart;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// easing functions; see http://easings.net
|
||||
//
|
||||
|
||||
/// ease8InOutQuad: 8-bit quadratic ease-in / ease-out function
|
||||
/// Takes around 13 cycles on AVR
|
||||
#if EASE8_C == 1
|
||||
LIB8STATIC uint8_t ease8InOutQuad( uint8_t i)
|
||||
{
|
||||
uint8_t j = i;
|
||||
if( j & 0x80 ) {
|
||||
j = 255 - j;
|
||||
}
|
||||
uint8_t jj = scale8( j, j);
|
||||
uint8_t jj2 = jj << 1;
|
||||
if( i & 0x80 ) {
|
||||
jj2 = 255 - jj2;
|
||||
}
|
||||
return jj2;
|
||||
}
|
||||
|
||||
#elif EASE8_AVRASM == 1
|
||||
// This AVR asm version of ease8InOutQuad preserves one more
|
||||
// low-bit of precision than the C version, and is also slightly
|
||||
// smaller and faster.
|
||||
LIB8STATIC uint8_t ease8InOutQuad(uint8_t val) {
|
||||
uint8_t j=val;
|
||||
asm volatile (
|
||||
"sbrc %[val], 7 \n"
|
||||
"com %[j] \n"
|
||||
"mul %[j], %[j] \n"
|
||||
"add r0, %[j] \n"
|
||||
"ldi %[j], 0 \n"
|
||||
"adc %[j], r1 \n"
|
||||
"lsl r0 \n" // carry = high bit of low byte of mul product
|
||||
"rol %[j] \n" // j = (j * 2) + carry // preserve add'l bit of precision
|
||||
"sbrc %[val], 7 \n"
|
||||
"com %[j] \n"
|
||||
"clr __zero_reg__ \n"
|
||||
: [j] "+&a" (j)
|
||||
: [val] "a" (val)
|
||||
: "r0", "r1"
|
||||
);
|
||||
return j;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "No implementation for ease8InOutQuad available."
|
||||
#endif
|
||||
|
||||
/// ease16InOutQuad: 16-bit quadratic ease-in / ease-out function
|
||||
// C implementation at this point
|
||||
LIB8STATIC uint16_t ease16InOutQuad( uint16_t i)
|
||||
{
|
||||
uint16_t j = i;
|
||||
if( j & 0x8000 ) {
|
||||
j = 65535 - j;
|
||||
}
|
||||
uint16_t jj = scale16( j, j);
|
||||
uint16_t jj2 = jj << 1;
|
||||
if( i & 0x8000 ) {
|
||||
jj2 = 65535 - jj2;
|
||||
}
|
||||
return jj2;
|
||||
}
|
||||
|
||||
|
||||
/// ease8InOutCubic: 8-bit cubic ease-in / ease-out function
|
||||
/// Takes around 18 cycles on AVR
|
||||
LIB8STATIC fract8 ease8InOutCubic( fract8 i)
|
||||
{
|
||||
uint8_t ii = scale8_LEAVING_R1_DIRTY( i, i);
|
||||
uint8_t iii = scale8_LEAVING_R1_DIRTY( ii, i);
|
||||
|
||||
uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
|
||||
|
||||
/* the code generated for the above *'s automatically
|
||||
cleans up R1, so there's no need to explicitily call
|
||||
cleanup_R1(); */
|
||||
|
||||
uint8_t result = r1;
|
||||
|
||||
// if we got "256", return 255:
|
||||
if( r1 & 0x100 ) {
|
||||
result = 255;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// ease8InOutApprox: fast, rough 8-bit ease-in/ease-out function
|
||||
/// shaped approximately like 'ease8InOutCubic',
|
||||
/// it's never off by more than a couple of percent
|
||||
/// from the actual cubic S-curve, and it executes
|
||||
/// more than twice as fast. Use when the cycles
|
||||
/// are more important than visual smoothness.
|
||||
/// Asm version takes around 7 cycles on AVR.
|
||||
|
||||
#if EASE8_C == 1
|
||||
LIB8STATIC fract8 ease8InOutApprox( fract8 i)
|
||||
{
|
||||
if( i < 64) {
|
||||
// start with slope 0.5
|
||||
i /= 2;
|
||||
} else if( i > (255 - 64)) {
|
||||
// end with slope 0.5
|
||||
i = 255 - i;
|
||||
i /= 2;
|
||||
i = 255 - i;
|
||||
} else {
|
||||
// in the middle, use slope 192/128 = 1.5
|
||||
i -= 64;
|
||||
i += (i / 2);
|
||||
i += 32;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#elif EASE8_AVRASM == 1
|
||||
LIB8STATIC uint8_t ease8InOutApprox( fract8 i)
|
||||
{
|
||||
// takes around 7 cycles on AVR
|
||||
asm volatile (
|
||||
" subi %[i], 64 \n\t"
|
||||
" cpi %[i], 128 \n\t"
|
||||
" brcc Lshift_%= \n\t"
|
||||
|
||||
// middle case
|
||||
" mov __tmp_reg__, %[i] \n\t"
|
||||
" lsr __tmp_reg__ \n\t"
|
||||
" add %[i], __tmp_reg__ \n\t"
|
||||
" subi %[i], 224 \n\t"
|
||||
" rjmp Ldone_%= \n\t"
|
||||
|
||||
// start or end case
|
||||
"Lshift_%=: \n\t"
|
||||
" lsr %[i] \n\t"
|
||||
" subi %[i], 96 \n\t"
|
||||
|
||||
"Ldone_%=: \n\t"
|
||||
|
||||
: [i] "+&a" (i)
|
||||
:
|
||||
: "r0", "r1"
|
||||
);
|
||||
return i;
|
||||
}
|
||||
#else
|
||||
#error "No implementation for ease8 available."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/// triwave8: triangle (sawtooth) wave generator. Useful for
|
||||
/// turning a one-byte ever-increasing value into a
|
||||
/// one-byte value that oscillates up and down.
|
||||
///
|
||||
/// input output
|
||||
/// 0..127 0..254 (positive slope)
|
||||
/// 128..255 254..0 (negative slope)
|
||||
///
|
||||
/// On AVR this function takes just three cycles.
|
||||
///
|
||||
LIB8STATIC uint8_t triwave8(uint8_t in)
|
||||
{
|
||||
if( in & 0x80) {
|
||||
in = 255 - in;
|
||||
}
|
||||
uint8_t out = in << 1;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// quadwave8 and cubicwave8: S-shaped wave generators (like 'sine').
|
||||
// Useful for turning a one-byte 'counter' value into a
|
||||
// one-byte oscillating value that moves smoothly up and down,
|
||||
// with an 'acceleration' and 'deceleration' curve.
|
||||
//
|
||||
// These are even faster than 'sin8', and have
|
||||
// slightly different curve shapes.
|
||||
//
|
||||
|
||||
/// quadwave8: quadratic waveform generator. Spends just a little more
|
||||
/// time at the limits than 'sine' does.
|
||||
LIB8STATIC uint8_t quadwave8(uint8_t in)
|
||||
{
|
||||
return ease8InOutQuad( triwave8( in));
|
||||
}
|
||||
|
||||
/// cubicwave8: cubic waveform generator. Spends visibly more time
|
||||
/// at the limits than 'sine' does.
|
||||
LIB8STATIC uint8_t cubicwave8(uint8_t in)
|
||||
{
|
||||
return ease8InOutCubic( triwave8( in));
|
||||
}
|
||||
|
||||
/// squarewave8: square wave generator. Useful for
|
||||
/// turning a one-byte ever-increasing value
|
||||
/// into a one-byte value that is either 0 or 255.
|
||||
/// The width of the output 'pulse' is
|
||||
/// determined by the pulsewidth argument:
|
||||
///
|
||||
///~~~
|
||||
/// If pulsewidth is 255, output is always 255.
|
||||
/// If pulsewidth < 255, then
|
||||
/// if input < pulsewidth then output is 255
|
||||
/// if input >= pulsewidth then output is 0
|
||||
///~~~
|
||||
///
|
||||
/// the output looking like:
|
||||
///
|
||||
///~~~
|
||||
/// 255 +--pulsewidth--+
|
||||
/// . | |
|
||||
/// 0 0 +--------(256-pulsewidth)--------
|
||||
///~~~
|
||||
///
|
||||
/// @param in
|
||||
/// @param pulsewidth
|
||||
/// @returns square wave output
|
||||
LIB8STATIC uint8_t squarewave8( uint8_t in, uint8_t pulsewidth)
|
||||
{
|
||||
if( in < pulsewidth || (pulsewidth == 255)) {
|
||||
return 255;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Beat generators - These functions produce waves at a given
|
||||
// number of 'beats per minute'. Internally, they use
|
||||
// the Arduino function 'millis' to track elapsed time.
|
||||
// Accuracy is a bit better than one part in a thousand.
|
||||
//
|
||||
// beat8( BPM ) returns an 8-bit value that cycles 'BPM' times
|
||||
// per minute, rising from 0 to 255, resetting to zero,
|
||||
// rising up again, etc.. The output of this function
|
||||
// is suitable for feeding directly into sin8, and cos8,
|
||||
// triwave8, quadwave8, and cubicwave8.
|
||||
// beat16( BPM ) returns a 16-bit value that cycles 'BPM' times
|
||||
// per minute, rising from 0 to 65535, resetting to zero,
|
||||
// rising up again, etc. The output of this function is
|
||||
// suitable for feeding directly into sin16 and cos16.
|
||||
// beat88( BPM88) is the same as beat16, except that the BPM88 argument
|
||||
// MUST be in Q8.8 fixed point format, e.g. 120BPM must
|
||||
// be specified as 120*256 = 30720.
|
||||
// beatsin8( BPM, uint8_t low, uint8_t high) returns an 8-bit value that
|
||||
// rises and falls in a sine wave, 'BPM' times per minute,
|
||||
// between the values of 'low' and 'high'.
|
||||
// beatsin16( BPM, uint16_t low, uint16_t high) returns a 16-bit value
|
||||
// that rises and falls in a sine wave, 'BPM' times per
|
||||
// minute, between the values of 'low' and 'high'.
|
||||
// beatsin88( BPM88, ...) is the same as beatsin16, except that the
|
||||
// BPM88 argument MUST be in Q8.8 fixed point format,
|
||||
// e.g. 120BPM must be specified as 120*256 = 30720.
|
||||
//
|
||||
// BPM can be supplied two ways. The simpler way of specifying BPM is as
|
||||
// a simple 8-bit integer from 1-255, (e.g., "120").
|
||||
// The more sophisticated way of specifying BPM allows for fractional
|
||||
// "Q8.8" fixed point number (an 'accum88') with an 8-bit integer part and
|
||||
// an 8-bit fractional part. The easiest way to construct this is to multiply
|
||||
// a floating point BPM value (e.g. 120.3) by 256, (e.g. resulting in 30796
|
||||
// in this case), and pass that as the 16-bit BPM argument.
|
||||
// "BPM88" MUST always be specified in Q8.8 format.
|
||||
//
|
||||
// Originally designed to make an entire animation project pulse with brightness.
|
||||
// For that effect, add this line just above your existing call to "FastLED.show()":
|
||||
//
|
||||
// uint8_t bright = beatsin8( 60 /*BPM*/, 192 /*dimmest*/, 255 /*brightest*/ ));
|
||||
// FastLED.setBrightness( bright );
|
||||
// FastLED.show();
|
||||
//
|
||||
// The entire animation will now pulse between brightness 192 and 255 once per second.
|
||||
|
||||
|
||||
// The beat generators need access to a millisecond counter.
|
||||
// On Arduino, this is "millis()". On other platforms, you'll
|
||||
// need to provide a function with this signature:
|
||||
// uint32_t get_millisecond_timer();
|
||||
// that provides similar functionality.
|
||||
// You can also force use of the get_millisecond_timer function
|
||||
// by #defining USE_GET_MILLISECOND_TIMER.
|
||||
#if (defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)
|
||||
// Forward declaration of Arduino function 'millis'.
|
||||
//uint32_t millis();
|
||||
#define GET_MILLIS millis
|
||||
#else
|
||||
uint32_t get_millisecond_timer(void);
|
||||
#define GET_MILLIS get_millisecond_timer
|
||||
#endif
|
||||
|
||||
// beat16 generates a 16-bit 'sawtooth' wave at a given BPM,
|
||||
/// with BPM specified in Q8.8 fixed-point format; e.g.
|
||||
/// for this function, 120 BPM MUST BE specified as
|
||||
/// 120*256 = 30720.
|
||||
/// If you just want to specify "120", use beat16 or beat8.
|
||||
LIB8STATIC uint16_t beat88( accum88 beats_per_minute_88, uint32_t timebase)
|
||||
{
|
||||
// BPM is 'beats per minute', or 'beats per 60000ms'.
|
||||
// To avoid using the (slower) division operator, we
|
||||
// want to convert 'beats per 60000ms' to 'beats per 65536ms',
|
||||
// and then use a simple, fast bit-shift to divide by 65536.
|
||||
//
|
||||
// The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256.
|
||||
// The conversion is accurate to about 0.05%, more or less,
|
||||
// e.g. if you ask for "120 BPM", you'll get about "119.93".
|
||||
return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
|
||||
}
|
||||
|
||||
/// beat16 generates a 16-bit 'sawtooth' wave at a given BPM
|
||||
LIB8STATIC uint16_t beat16( accum88 beats_per_minute, uint32_t timebase)
|
||||
{
|
||||
// Convert simple 8-bit BPM's to full Q8.8 accum88's if needed
|
||||
if( beats_per_minute < 256) beats_per_minute <<= 8;
|
||||
return beat88(beats_per_minute, timebase);
|
||||
}
|
||||
|
||||
/// beat8 generates an 8-bit 'sawtooth' wave at a given BPM
|
||||
LIB8STATIC uint8_t beat8( accum88 beats_per_minute, uint32_t timebase)
|
||||
{
|
||||
return beat16( beats_per_minute, timebase) >> 8;
|
||||
}
|
||||
|
||||
/// beatsin88 generates a 16-bit sine wave at a given BPM,
|
||||
/// that oscillates within a given range.
|
||||
/// For this function, BPM MUST BE SPECIFIED as
|
||||
/// a Q8.8 fixed-point value; e.g. 120BPM must be
|
||||
/// specified as 120*256 = 30720.
|
||||
/// If you just want to specify "120", use beatsin16 or beatsin8.
|
||||
LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
|
||||
{
|
||||
uint16_t beat = beat88( beats_per_minute_88, timebase);
|
||||
uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
|
||||
uint16_t rangewidth = highest - lowest;
|
||||
uint16_t scaledbeat = scale16( beatsin, rangewidth);
|
||||
uint16_t result = lowest + scaledbeat;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// beatsin16 generates a 16-bit sine wave at a given BPM,
|
||||
/// that oscillates within a given range.
|
||||
LIB8STATIC uint16_t beatsin16(accum88 beats_per_minute, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
|
||||
{
|
||||
uint16_t beat = beat16( beats_per_minute, timebase);
|
||||
uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
|
||||
uint16_t rangewidth = highest - lowest;
|
||||
uint16_t scaledbeat = scale16( beatsin, rangewidth);
|
||||
uint16_t result = lowest + scaledbeat;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// beatsin8 generates an 8-bit sine wave at a given BPM,
|
||||
/// that oscillates within a given range.
|
||||
LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest, uint8_t highest, uint32_t timebase, uint8_t phase_offset)
|
||||
{
|
||||
uint8_t beat = beat8( beats_per_minute, timebase);
|
||||
uint8_t beatsin = sin8( beat + phase_offset);
|
||||
uint8_t rangewidth = highest - lowest;
|
||||
uint8_t scaledbeat = scale8( beatsin, rangewidth);
|
||||
uint8_t result = lowest + scaledbeat;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// Return the current seconds since boot in a 16-bit value. Used as part of the
|
||||
/// "every N time-periods" mechanism
|
||||
LIB8STATIC uint16_t seconds16(void)
|
||||
{
|
||||
uint32_t ms = GET_MILLIS();
|
||||
uint16_t s16;
|
||||
s16 = ms / 1000;
|
||||
return s16;
|
||||
}
|
||||
|
||||
/// Return the current minutes since boot in a 16-bit value. Used as part of the
|
||||
/// "every N time-periods" mechanism
|
||||
LIB8STATIC uint16_t minutes16(void)
|
||||
{
|
||||
uint32_t ms = GET_MILLIS();
|
||||
uint16_t m16;
|
||||
m16 = (ms / (60000L)) & 0xFFFF;
|
||||
return m16;
|
||||
}
|
||||
|
||||
/// Return the current hours since boot in an 8-bit value. Used as part of the
|
||||
/// "every N time-periods" mechanism
|
||||
LIB8STATIC uint8_t hours8(void)
|
||||
{
|
||||
uint32_t ms = GET_MILLIS();
|
||||
uint8_t h8;
|
||||
h8 = (ms / (3600000L)) & 0xFF;
|
||||
return h8;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif
|
@ -0,0 +1,552 @@
|
||||
#ifndef __INC_LIB8TION_MATH_H
|
||||
#define __INC_LIB8TION_MATH_H
|
||||
|
||||
#include "scale8.h"
|
||||
|
||||
///@ingroup lib8tion
|
||||
|
||||
///@defgroup Math Basic math operations
|
||||
/// Fast, efficient 8-bit math functions specifically
|
||||
/// designed for high-performance LED programming.
|
||||
///
|
||||
/// Because of the AVR(Arduino) and ARM assembly language
|
||||
/// implementations provided, using these functions often
|
||||
/// results in smaller and faster code than the equivalent
|
||||
/// program using plain "C" arithmetic and logic.
|
||||
///@{
|
||||
|
||||
|
||||
/// add one byte to another, saturating at 0xFF
|
||||
/// @param i - first byte to add
|
||||
/// @param j - second byte to add
|
||||
/// @returns the sum of i & j, capped at 0xFF
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t qadd8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if QADD8_C == 1
|
||||
uint16_t t = i + j;
|
||||
if (t > 255) t = 255;
|
||||
return t;
|
||||
#elif QADD8_AVRASM == 1
|
||||
asm volatile(
|
||||
/* First, add j to i, conditioning the C flag */
|
||||
"add %0, %1 \n\t"
|
||||
|
||||
/* Now test the C flag.
|
||||
If C is clear, we branch around a load of 0xFF into i.
|
||||
If C is set, we go ahead and load 0xFF into i.
|
||||
*/
|
||||
"brcc L_%= \n\t"
|
||||
"ldi %0, 0xFF \n\t"
|
||||
"L_%=: "
|
||||
: "+a" (i)
|
||||
: "a" (j) );
|
||||
return i;
|
||||
#elif QADD8_ARM_DSP_ASM == 1
|
||||
asm volatile( "uqadd8 %0, %0, %1" : "+r" (i) : "r" (j));
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for qadd8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Add one byte to another, saturating at 0x7F
|
||||
/// @param i - first byte to add
|
||||
/// @param j - second byte to add
|
||||
/// @returns the sum of i & j, capped at 0xFF
|
||||
LIB8STATIC_ALWAYS_INLINE int8_t qadd7( int8_t i, int8_t j)
|
||||
{
|
||||
#if QADD7_C == 1
|
||||
int16_t t = i + j;
|
||||
if (t > 127) t = 127;
|
||||
return t;
|
||||
#elif QADD7_AVRASM == 1
|
||||
asm volatile(
|
||||
/* First, add j to i, conditioning the V flag */
|
||||
"add %0, %1 \n\t"
|
||||
|
||||
/* Now test the V flag.
|
||||
If V is clear, we branch around a load of 0x7F into i.
|
||||
If V is set, we go ahead and load 0x7F into i.
|
||||
*/
|
||||
"brvc L_%= \n\t"
|
||||
"ldi %0, 0x7F \n\t"
|
||||
"L_%=: "
|
||||
: "+a" (i)
|
||||
: "a" (j) );
|
||||
|
||||
return i;
|
||||
#elif QADD7_ARM_DSP_ASM == 1
|
||||
asm volatile( "qadd8 %0, %0, %1" : "+r" (i) : "r" (j));
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for qadd7 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// subtract one byte from another, saturating at 0x00
|
||||
/// @returns i - j with a floor of 0
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t qsub8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if QSUB8_C == 1
|
||||
int16_t t = i - j;
|
||||
if (t < 0) t = 0;
|
||||
return t;
|
||||
#elif QSUB8_AVRASM == 1
|
||||
|
||||
asm volatile(
|
||||
/* First, subtract j from i, conditioning the C flag */
|
||||
"sub %0, %1 \n\t"
|
||||
|
||||
/* Now test the C flag.
|
||||
If C is clear, we branch around a load of 0x00 into i.
|
||||
If C is set, we go ahead and load 0x00 into i.
|
||||
*/
|
||||
"brcc L_%= \n\t"
|
||||
"ldi %0, 0x00 \n\t"
|
||||
"L_%=: "
|
||||
: "+a" (i)
|
||||
: "a" (j) );
|
||||
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for qsub8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// add one byte to another, with one byte result
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t add8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if ADD8_C == 1
|
||||
uint16_t t = i + j;
|
||||
return t;
|
||||
#elif ADD8_AVRASM == 1
|
||||
// Add j to i, period.
|
||||
asm volatile( "add %0, %1" : "+a" (i) : "a" (j));
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for add8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// add one byte to another, with one byte result
|
||||
LIB8STATIC_ALWAYS_INLINE uint16_t add8to16( uint8_t i, uint16_t j)
|
||||
{
|
||||
#if ADD8_C == 1
|
||||
uint16_t t = i + j;
|
||||
return t;
|
||||
#elif ADD8_AVRASM == 1
|
||||
// Add i(one byte) to j(two bytes)
|
||||
asm volatile( "add %A[j], %[i] \n\t"
|
||||
"adc %B[j], __zero_reg__ \n\t"
|
||||
: [j] "+a" (j)
|
||||
: [i] "a" (i)
|
||||
);
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for add8to16 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// subtract one byte from another, 8-bit result
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t sub8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if SUB8_C == 1
|
||||
int16_t t = i - j;
|
||||
return t;
|
||||
#elif SUB8_AVRASM == 1
|
||||
// Subtract j from i, period.
|
||||
asm volatile( "sub %0, %1" : "+a" (i) : "a" (j));
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for sub8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Calculate an integer average of two unsigned
|
||||
/// 8-bit integer values (uint8_t).
|
||||
/// Fractional results are rounded down, e.g. avg8(20,41) = 30
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t avg8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if AVG8_C == 1
|
||||
return (i + j) >> 1;
|
||||
#elif AVG8_AVRASM == 1
|
||||
asm volatile(
|
||||
/* First, add j to i, 9th bit overflows into C flag */
|
||||
"add %0, %1 \n\t"
|
||||
/* Divide by two, moving C flag into high 8th bit */
|
||||
"ror %0 \n\t"
|
||||
: "+a" (i)
|
||||
: "a" (j) );
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for avg8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Calculate an integer average of two unsigned
|
||||
/// 16-bit integer values (uint16_t).
|
||||
/// Fractional results are rounded down, e.g. avg16(20,41) = 30
|
||||
LIB8STATIC_ALWAYS_INLINE uint16_t avg16( uint16_t i, uint16_t j)
|
||||
{
|
||||
#if AVG16_C == 1
|
||||
return (uint32_t)((uint32_t)(i) + (uint32_t)(j)) >> 1;
|
||||
#elif AVG16_AVRASM == 1
|
||||
asm volatile(
|
||||
/* First, add jLo (heh) to iLo, 9th bit overflows into C flag */
|
||||
"add %A[i], %A[j] \n\t"
|
||||
/* Now, add C + jHi to iHi, 17th bit overflows into C flag */
|
||||
"adc %B[i], %B[j] \n\t"
|
||||
/* Divide iHi by two, moving C flag into high 16th bit, old 9th bit now in C */
|
||||
"ror %B[i] \n\t"
|
||||
/* Divide iLo by two, moving C flag into high 8th bit */
|
||||
"ror %A[i] \n\t"
|
||||
: [i] "+a" (i)
|
||||
: [j] "a" (j) );
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for avg16 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Calculate an integer average of two signed 7-bit
|
||||
/// integers (int8_t)
|
||||
/// If the first argument is even, result is rounded down.
|
||||
/// If the first argument is odd, result is result up.
|
||||
LIB8STATIC_ALWAYS_INLINE int8_t avg7( int8_t i, int8_t j)
|
||||
{
|
||||
#if AVG7_C == 1
|
||||
return ((i + j) >> 1) + (i & 0x1);
|
||||
#elif AVG7_AVRASM == 1
|
||||
asm volatile(
|
||||
"asr %1 \n\t"
|
||||
"asr %0 \n\t"
|
||||
"adc %0, %1 \n\t"
|
||||
: "+a" (i)
|
||||
: "a" (j) );
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for avg7 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Calculate an integer average of two signed 15-bit
|
||||
/// integers (int16_t)
|
||||
/// If the first argument is even, result is rounded down.
|
||||
/// If the first argument is odd, result is result up.
|
||||
LIB8STATIC_ALWAYS_INLINE int16_t avg15( int16_t i, int16_t j)
|
||||
{
|
||||
#if AVG15_C == 1
|
||||
return ((int32_t)((int32_t)(i) + (int32_t)(j)) >> 1) + (i & 0x1);
|
||||
#elif AVG15_AVRASM == 1
|
||||
asm volatile(
|
||||
/* first divide j by 2, throwing away lowest bit */
|
||||
"asr %B[j] \n\t"
|
||||
"ror %A[j] \n\t"
|
||||
/* now divide i by 2, with lowest bit going into C */
|
||||
"asr %B[i] \n\t"
|
||||
"ror %A[i] \n\t"
|
||||
/* add j + C to i */
|
||||
"adc %A[i], %A[j] \n\t"
|
||||
"adc %B[i], %B[j] \n\t"
|
||||
: [i] "+a" (i)
|
||||
: [j] "a" (j) );
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for avg15 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the remainder of one unsigned 8-bit
|
||||
/// value divided by anoter, aka A % M.
|
||||
/// Implemented by repeated subtraction, which is
|
||||
/// very compact, and very fast if A is 'probably'
|
||||
/// less than M. If A is a large multiple of M,
|
||||
/// the loop has to execute multiple times. However,
|
||||
/// even in that case, the loop is only two
|
||||
/// instructions long on AVR, i.e., quick.
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t mod8( uint8_t a, uint8_t m)
|
||||
{
|
||||
#if defined(__AVR__)
|
||||
asm volatile (
|
||||
"L_%=: sub %[a],%[m] \n\t"
|
||||
" brcc L_%= \n\t"
|
||||
" add %[a],%[m] \n\t"
|
||||
: [a] "+r" (a)
|
||||
: [m] "r" (m)
|
||||
);
|
||||
#else
|
||||
while( a >= m) a -= m;
|
||||
#endif
|
||||
return a;
|
||||
}
|
||||
|
||||
/// Add two numbers, and calculate the modulo
|
||||
/// of the sum and a third number, M.
|
||||
/// In other words, it returns (A+B) % M.
|
||||
/// It is designed as a compact mechanism for
|
||||
/// incrementing a 'mode' switch and wrapping
|
||||
/// around back to 'mode 0' when the switch
|
||||
/// goes past the end of the available range.
|
||||
/// e.g. if you have seven modes, this switches
|
||||
/// to the next one and wraps around if needed:
|
||||
/// mode = addmod8( mode, 1, 7);
|
||||
///LIB8STATIC_ALWAYS_INLINESee 'mod8' for notes on performance.
|
||||
LIB8STATIC uint8_t addmod8( uint8_t a, uint8_t b, uint8_t m)
|
||||
{
|
||||
#if defined(__AVR__)
|
||||
asm volatile (
|
||||
" add %[a],%[b] \n\t"
|
||||
"L_%=: sub %[a],%[m] \n\t"
|
||||
" brcc L_%= \n\t"
|
||||
" add %[a],%[m] \n\t"
|
||||
: [a] "+r" (a)
|
||||
: [b] "r" (b), [m] "r" (m)
|
||||
);
|
||||
#else
|
||||
a += b;
|
||||
while( a >= m) a -= m;
|
||||
#endif
|
||||
return a;
|
||||
}
|
||||
|
||||
/// Subtract two numbers, and calculate the modulo
|
||||
/// of the difference and a third number, M.
|
||||
/// In other words, it returns (A-B) % M.
|
||||
/// It is designed as a compact mechanism for
|
||||
/// incrementing a 'mode' switch and wrapping
|
||||
/// around back to 'mode 0' when the switch
|
||||
/// goes past the end of the available range.
|
||||
/// e.g. if you have seven modes, this switches
|
||||
/// to the next one and wraps around if needed:
|
||||
/// mode = addmod8( mode, 1, 7);
|
||||
///LIB8STATIC_ALWAYS_INLINESee 'mod8' for notes on performance.
|
||||
LIB8STATIC uint8_t submod8( uint8_t a, uint8_t b, uint8_t m)
|
||||
{
|
||||
#if defined(__AVR__)
|
||||
asm volatile (
|
||||
" sub %[a],%[b] \n\t"
|
||||
"L_%=: sub %[a],%[m] \n\t"
|
||||
" brcc L_%= \n\t"
|
||||
" add %[a],%[m] \n\t"
|
||||
: [a] "+r" (a)
|
||||
: [b] "r" (b), [m] "r" (m)
|
||||
);
|
||||
#else
|
||||
a -= b;
|
||||
while( a >= m) a -= m;
|
||||
#endif
|
||||
return a;
|
||||
}
|
||||
|
||||
/// 8x8 bit multiplication, with 8 bit result
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t mul8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if MUL8_C == 1
|
||||
return ((uint16_t)i * (uint16_t)(j) ) & 0xFF;
|
||||
#elif MUL8_AVRASM == 1
|
||||
asm volatile(
|
||||
/* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
|
||||
"mul %0, %1 \n\t"
|
||||
/* Extract the LOW 8-bits (r0) */
|
||||
"mov %0, r0 \n\t"
|
||||
/* Restore r1 to "0"; it's expected to always be that */
|
||||
"clr __zero_reg__ \n\t"
|
||||
: "+a" (i)
|
||||
: "a" (j)
|
||||
: "r0", "r1");
|
||||
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for mul8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// saturating 8x8 bit multiplication, with 8 bit result
|
||||
/// @returns the product of i * j, capping at 0xFF
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t qmul8( uint8_t i, uint8_t j)
|
||||
{
|
||||
#if QMUL8_C == 1
|
||||
int p = ((uint16_t)i * (uint16_t)(j) );
|
||||
if( p > 255) p = 255;
|
||||
return p;
|
||||
#elif QMUL8_AVRASM == 1
|
||||
asm volatile(
|
||||
/* Multiply 8-bit i * 8-bit j, giving 16-bit r1,r0 */
|
||||
" mul %0, %1 \n\t"
|
||||
/* If high byte of result is zero, all is well. */
|
||||
" tst r1 \n\t"
|
||||
" breq Lnospill_%= \n\t"
|
||||
/* If high byte of result > 0, saturate low byte to 0xFF */
|
||||
" ldi %0,0xFF \n\t"
|
||||
" rjmp Ldone_%= \n\t"
|
||||
"Lnospill_%=: \n\t"
|
||||
/* Extract the LOW 8-bits (r0) */
|
||||
" mov %0, r0 \n\t"
|
||||
"Ldone_%=: \n\t"
|
||||
/* Restore r1 to "0"; it's expected to always be that */
|
||||
" clr __zero_reg__ \n\t"
|
||||
: "+a" (i)
|
||||
: "a" (j)
|
||||
: "r0", "r1");
|
||||
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for qmul8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// take abs() of a signed 8-bit uint8_t
|
||||
LIB8STATIC_ALWAYS_INLINE int8_t abs8( int8_t i)
|
||||
{
|
||||
#if ABS8_C == 1
|
||||
if( i < 0) i = -i;
|
||||
return i;
|
||||
#elif ABS8_AVRASM == 1
|
||||
|
||||
|
||||
asm volatile(
|
||||
/* First, check the high bit, and prepare to skip if it's clear */
|
||||
"sbrc %0, 7 \n"
|
||||
|
||||
/* Negate the value */
|
||||
"neg %0 \n"
|
||||
|
||||
: "+r" (i) : "r" (i) );
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for abs8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// square root for 16-bit integers
|
||||
/// About three times faster and five times smaller
|
||||
/// than Arduino's general sqrt on AVR.
|
||||
LIB8STATIC uint8_t sqrt16(uint16_t x)
|
||||
{
|
||||
if( x <= 1) {
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8_t low = 1; // lower bound
|
||||
uint8_t hi, mid;
|
||||
|
||||
if( x > 7904) {
|
||||
hi = 255;
|
||||
} else {
|
||||
hi = (x >> 5) + 8; // initial estimate for upper bound
|
||||
}
|
||||
|
||||
do {
|
||||
mid = (low + hi) >> 1;
|
||||
if ((uint16_t)(mid * mid) > x) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
if( mid == 255) {
|
||||
return 255;
|
||||
}
|
||||
low = mid + 1;
|
||||
}
|
||||
} while (hi >= low);
|
||||
|
||||
return low - 1;
|
||||
}
|
||||
|
||||
/// blend a variable proproportion(0-255) of one byte to another
|
||||
/// @param a - the starting byte value
|
||||
/// @param b - the byte value to blend toward
|
||||
/// @param amountOfB - the proportion (0-255) of b to blend
|
||||
/// @returns a byte value between a and b, inclusive
|
||||
#if (FASTLED_BLEND_FIXED == 1)
|
||||
LIB8STATIC uint8_t blend8( uint8_t a, uint8_t b, uint8_t amountOfB)
|
||||
{
|
||||
#if BLEND8_C == 1
|
||||
uint16_t partial;
|
||||
uint8_t result;
|
||||
|
||||
uint8_t amountOfA = 255 - amountOfB;
|
||||
|
||||
partial = (a * amountOfA);
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
partial += a;
|
||||
//partial = add8to16( a, partial);
|
||||
#endif
|
||||
|
||||
partial += (b * amountOfB);
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
partial += b;
|
||||
//partial = add8to16( b, partial);
|
||||
#endif
|
||||
|
||||
result = partial >> 8;
|
||||
|
||||
return result;
|
||||
|
||||
#elif BLEND8_AVRASM == 1
|
||||
uint16_t partial;
|
||||
uint8_t result;
|
||||
|
||||
asm volatile (
|
||||
/* partial = b * amountOfB */
|
||||
" mul %[b], %[amountOfB] \n\t"
|
||||
" movw %A[partial], r0 \n\t"
|
||||
|
||||
/* amountOfB (aka amountOfA) = 255 - amountOfB */
|
||||
" com %[amountOfB] \n\t"
|
||||
|
||||
/* partial += a * amountOfB (aka amountOfA) */
|
||||
" mul %[a], %[amountOfB] \n\t"
|
||||
|
||||
" add %A[partial], r0 \n\t"
|
||||
" adc %B[partial], r1 \n\t"
|
||||
|
||||
" clr __zero_reg__ \n\t"
|
||||
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
/* partial += a */
|
||||
" add %A[partial], %[a] \n\t"
|
||||
" adc %B[partial], __zero_reg__ \n\t"
|
||||
|
||||
// partial += b
|
||||
" add %A[partial], %[b] \n\t"
|
||||
" adc %B[partial], __zero_reg__ \n\t"
|
||||
#endif
|
||||
|
||||
: [partial] "=r" (partial),
|
||||
[amountOfB] "+a" (amountOfB)
|
||||
: [a] "a" (a),
|
||||
[b] "a" (b)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
result = partial >> 8;
|
||||
|
||||
return result;
|
||||
|
||||
#else
|
||||
#error "No implementation for blend8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
LIB8STATIC uint8_t blend8( uint8_t a, uint8_t b, uint8_t amountOfB)
|
||||
{
|
||||
// This version loses precision in the integer math
|
||||
// and can actually return results outside of the range
|
||||
// from a to b. Its use is not recommended.
|
||||
uint8_t result;
|
||||
uint8_t amountOfA = 255 - amountOfB;
|
||||
result = scale8_LEAVING_R1_DIRTY( a, amountOfA)
|
||||
+ scale8_LEAVING_R1_DIRTY( b, amountOfB);
|
||||
cleanup_R1();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
///@}
|
||||
#endif
|
@ -0,0 +1,94 @@
|
||||
#ifndef __INC_LIB8TION_RANDOM_H
|
||||
#define __INC_LIB8TION_RANDOM_H
|
||||
///@ingroup lib8tion
|
||||
|
||||
///@defgroup Random Fast random number generators
|
||||
/// Fast 8- and 16- bit unsigned random numbers.
|
||||
/// Significantly faster than Arduino random(), but
|
||||
/// also somewhat less random. You can add entropy.
|
||||
///@{
|
||||
|
||||
// X(n+1) = (2053 * X(n)) + 13849)
|
||||
#define FASTLED_RAND16_2053 ((uint16_t)(2053))
|
||||
#define FASTLED_RAND16_13849 ((uint16_t)(13849))
|
||||
|
||||
/// random number seed
|
||||
extern uint16_t rand16seed;// = RAND16_SEED;
|
||||
|
||||
/// Generate an 8-bit random number
|
||||
LIB8STATIC uint8_t random8(void)
|
||||
{
|
||||
rand16seed = (rand16seed * FASTLED_RAND16_2053) + FASTLED_RAND16_13849;
|
||||
// return the sum of the high and low bytes, for better
|
||||
// mixing and non-sequential correlation
|
||||
return (uint8_t)(((uint8_t)(rand16seed & 0xFF)) +
|
||||
((uint8_t)(rand16seed >> 8)));
|
||||
}
|
||||
|
||||
/// Generate a 16 bit random number
|
||||
LIB8STATIC uint16_t random16(void)
|
||||
{
|
||||
rand16seed = (rand16seed * FASTLED_RAND16_2053) + FASTLED_RAND16_13849;
|
||||
return rand16seed;
|
||||
}
|
||||
|
||||
/// Generate an 8-bit random number between 0 and lim
|
||||
/// @param lim the upper bound for the result
|
||||
LIB8STATIC uint8_t random8_max(uint8_t lim)
|
||||
{
|
||||
uint8_t r = random8();
|
||||
r = (r*lim) >> 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Generate an 8-bit random number in the given range
|
||||
/// @param min the lower bound for the random number
|
||||
/// @param lim the upper bound for the random number
|
||||
LIB8STATIC uint8_t random8_min_max(uint8_t min, uint8_t lim)
|
||||
{
|
||||
uint8_t delta = lim - min;
|
||||
uint8_t r = random8_max(delta) + min;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Generate an 16-bit random number between 0 and lim
|
||||
/// @param lim the upper bound for the result
|
||||
LIB8STATIC uint16_t random16_max(uint16_t lim)
|
||||
{
|
||||
uint16_t r = random16();
|
||||
uint32_t p = (uint32_t)lim * (uint32_t)r;
|
||||
r = p >> 16;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Generate an 16-bit random number in the given range
|
||||
/// @param min the lower bound for the random number
|
||||
/// @param lim the upper bound for the random number
|
||||
LIB8STATIC uint16_t random16_min_max( uint16_t min, uint16_t lim)
|
||||
{
|
||||
uint16_t delta = lim - min;
|
||||
uint16_t r = random16_max(delta) + min;
|
||||
return r;
|
||||
}
|
||||
|
||||
/// Set the 16-bit seed used for the random number generator
|
||||
LIB8STATIC void random16_set_seed(uint16_t seed)
|
||||
{
|
||||
rand16seed = seed;
|
||||
}
|
||||
|
||||
/// Get the current seed value for the random number generator
|
||||
LIB8STATIC uint16_t random16_get_seed(void)
|
||||
{
|
||||
return rand16seed;
|
||||
}
|
||||
|
||||
/// Add entropy into the random number generator
|
||||
LIB8STATIC void random16_add_entropy(uint16_t entropy)
|
||||
{
|
||||
rand16seed += entropy;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif
|
@ -0,0 +1,542 @@
|
||||
#ifndef __INC_LIB8TION_SCALE_H
|
||||
#define __INC_LIB8TION_SCALE_H
|
||||
|
||||
///@ingroup lib8tion
|
||||
|
||||
///@defgroup Scaling Scaling functions
|
||||
/// Fast, efficient 8-bit scaling functions specifically
|
||||
/// designed for high-performance LED programming.
|
||||
///
|
||||
/// Because of the AVR(Arduino) and ARM assembly language
|
||||
/// implementations provided, using these functions often
|
||||
/// results in smaller and faster code than the equivalent
|
||||
/// program using plain "C" arithmetic and logic.
|
||||
///@{
|
||||
|
||||
/// scale one byte by a second one, which is treated as
|
||||
/// the numerator of a fraction whose denominator is 256
|
||||
/// In other words, it computes i * (scale / 256)
|
||||
/// 4 clocks AVR with MUL, 2 clocks ARM
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t scale8( uint8_t i, fract8 scale)
|
||||
{
|
||||
#if SCALE8_C == 1
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
return (((uint16_t)i) * (1+(uint16_t)(scale))) >> 8;
|
||||
#else
|
||||
return ((uint16_t)i * (uint16_t)(scale) ) >> 8;
|
||||
#endif
|
||||
#elif SCALE8_AVRASM == 1
|
||||
#if defined(LIB8_ATTINY)
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
uint8_t work=i;
|
||||
#else
|
||||
uint8_t work=0;
|
||||
#endif
|
||||
uint8_t cnt=0x80;
|
||||
asm volatile(
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
" inc %[scale] \n\t"
|
||||
" breq DONE_%= \n\t"
|
||||
" clr %[work] \n\t"
|
||||
#endif
|
||||
"LOOP_%=: \n\t"
|
||||
/*" sbrc %[scale], 0 \n\t"
|
||||
" add %[work], %[i] \n\t"
|
||||
" ror %[work] \n\t"
|
||||
" lsr %[scale] \n\t"
|
||||
" clc \n\t"*/
|
||||
" sbrc %[scale], 0 \n\t"
|
||||
" add %[work], %[i] \n\t"
|
||||
" ror %[work] \n\t"
|
||||
" lsr %[scale] \n\t"
|
||||
" lsr %[cnt] \n\t"
|
||||
"brcc LOOP_%= \n\t"
|
||||
"DONE_%=: \n\t"
|
||||
: [work] "+r" (work), [cnt] "+r" (cnt)
|
||||
: [scale] "r" (scale), [i] "r" (i)
|
||||
:
|
||||
);
|
||||
return work;
|
||||
#else
|
||||
asm volatile(
|
||||
#if (FASTLED_SCALE8_FIXED==1)
|
||||
// Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
|
||||
"mul %0, %1 \n\t"
|
||||
// Add i to r0, possibly setting the carry flag
|
||||
"add r0, %0 \n\t"
|
||||
// load the immediate 0 into i (note, this does _not_ touch any flags)
|
||||
"ldi %0, 0x00 \n\t"
|
||||
// walk and chew gum at the same time
|
||||
"adc %0, r1 \n\t"
|
||||
#else
|
||||
/* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
|
||||
"mul %0, %1 \n\t"
|
||||
/* Move the high 8-bits of the product (r1) back to i */
|
||||
"mov %0, r1 \n\t"
|
||||
/* Restore r1 to "0"; it's expected to always be that */
|
||||
#endif
|
||||
"clr __zero_reg__ \n\t"
|
||||
|
||||
: "+a" (i) /* writes to i */
|
||||
: "a" (scale) /* uses scale */
|
||||
: "r0", "r1" /* clobbers r0, r1 */ );
|
||||
|
||||
/* Return the result */
|
||||
return i;
|
||||
#endif
|
||||
#else
|
||||
#error "No implementation for scale8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// The "video" version of scale8 guarantees that the output will
|
||||
/// be only be zero if one or both of the inputs are zero. If both
|
||||
/// inputs are non-zero, the output is guaranteed to be non-zero.
|
||||
/// This makes for better 'video'/LED dimming, at the cost of
|
||||
/// several additional cycles.
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video( uint8_t i, fract8 scale)
|
||||
{
|
||||
#if SCALE8_C == 1 || defined(LIB8_ATTINY)
|
||||
uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
|
||||
// uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
|
||||
// uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale;
|
||||
return j;
|
||||
#elif SCALE8_AVRASM == 1
|
||||
uint8_t j=0;
|
||||
asm volatile(
|
||||
" tst %[i]\n\t"
|
||||
" breq L_%=\n\t"
|
||||
" mul %[i], %[scale]\n\t"
|
||||
" mov %[j], r1\n\t"
|
||||
" clr __zero_reg__\n\t"
|
||||
" cpse %[scale], r1\n\t"
|
||||
" subi %[j], 0xFF\n\t"
|
||||
"L_%=: \n\t"
|
||||
: [j] "+a" (j)
|
||||
: [i] "a" (i), [scale] "a" (scale)
|
||||
: "r0", "r1");
|
||||
|
||||
return j;
|
||||
// uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
|
||||
// asm volatile(
|
||||
// " tst %0 \n"
|
||||
// " breq L_%= \n"
|
||||
// " mul %0, %1 \n"
|
||||
// " mov %0, r1 \n"
|
||||
// " add %0, %2 \n"
|
||||
// " clr __zero_reg__ \n"
|
||||
// "L_%=: \n"
|
||||
|
||||
// : "+a" (i)
|
||||
// : "a" (scale), "a" (nonzeroscale)
|
||||
// : "r0", "r1");
|
||||
|
||||
// // Return the result
|
||||
// return i;
|
||||
#else
|
||||
#error "No implementation for scale8_video available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// This version of scale8 does not clean up the R1 register on AVR
|
||||
/// If you are doing several 'scale8's in a row, use this, and
|
||||
/// then explicitly call cleanup_R1.
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY( uint8_t i, fract8 scale)
|
||||
{
|
||||
#if SCALE8_C == 1
|
||||
#if (FASTLED_SCALE8_FIXED == 1)
|
||||
return (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8;
|
||||
#else
|
||||
return ((int)i * (int)(scale) ) >> 8;
|
||||
#endif
|
||||
#elif SCALE8_AVRASM == 1
|
||||
asm volatile(
|
||||
#if (FASTLED_SCALE8_FIXED==1)
|
||||
// Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0
|
||||
"mul %0, %1 \n\t"
|
||||
// Add i to r0, possibly setting the carry flag
|
||||
"add r0, %0 \n\t"
|
||||
// load the immediate 0 into i (note, this does _not_ touch any flags)
|
||||
"ldi %0, 0x00 \n\t"
|
||||
// walk and chew gum at the same time
|
||||
"adc %0, r1 \n\t"
|
||||
#else
|
||||
/* Multiply 8-bit i * 8-bit scale, giving 16-bit r1,r0 */
|
||||
"mul %0, %1 \n\t"
|
||||
/* Move the high 8-bits of the product (r1) back to i */
|
||||
"mov %0, r1 \n\t"
|
||||
#endif
|
||||
/* R1 IS LEFT DIRTY HERE; YOU MUST ZERO IT OUT YOURSELF */
|
||||
/* "clr __zero_reg__ \n\t" */
|
||||
|
||||
: "+a" (i) /* writes to i */
|
||||
: "a" (scale) /* uses scale */
|
||||
: "r0", "r1" /* clobbers r0, r1 */ );
|
||||
|
||||
// Return the result
|
||||
return i;
|
||||
#else
|
||||
#error "No implementation for scale8_LEAVING_R1_DIRTY available."
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// This version of scale8_video does not clean up the R1 register on AVR
|
||||
/// If you are doing several 'scale8_video's in a row, use this, and
|
||||
/// then explicitly call cleanup_R1.
|
||||
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract8 scale)
|
||||
{
|
||||
#if SCALE8_C == 1 || defined(LIB8_ATTINY)
|
||||
uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
|
||||
// uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
|
||||
// uint8_t j = (i == 0) ? 0 : (((int)i * (int)(scale) ) >> 8) + nonzeroscale;
|
||||
return j;
|
||||
#elif SCALE8_AVRASM == 1
|
||||
uint8_t j=0;
|
||||
asm volatile(
|
||||
" tst %[i]\n\t"
|
||||
" breq L_%=\n\t"
|
||||
" mul %[i], %[scale]\n\t"
|
||||
" mov %[j], r1\n\t"
|
||||
" breq L_%=\n\t"
|
||||
" subi %[j], 0xFF\n\t"
|
||||
"L_%=: \n\t"
|
||||
: [j] "+a" (j)
|
||||
: [i] "a" (i), [scale] "a" (scale)
|
||||
: "r0", "r1");
|
||||
|
||||
return j;
|
||||
// uint8_t nonzeroscale = (scale != 0) ? 1 : 0;
|
||||
// asm volatile(
|
||||
// " tst %0 \n"
|
||||
// " breq L_%= \n"
|
||||
// " mul %0, %1 \n"
|
||||
// " mov %0, r1 \n"
|
||||
// " add %0, %2 \n"
|
||||
// " clr __zero_reg__ \n"
|
||||
// "L_%=: \n"
|
||||
|
||||
// : "+a" (i)
|
||||
// : "a" (scale), "a" (nonzeroscale)
|
||||
// : "r0", "r1");
|
||||
|
||||
// // Return the result
|
||||
// return i;
|
||||
#else
|
||||
#error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls
|
||||
LIB8STATIC_ALWAYS_INLINE void cleanup_R1(void)
|
||||
{
|
||||
#if CLEANUP_R1_AVRASM == 1
|
||||
// Restore r1 to "0"; it's expected to always be that
|
||||
asm volatile( "clr __zero_reg__ \n\t" : : : "r1" );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// scale a 16-bit unsigned value by an 8-bit value,
|
||||
/// considered as numerator of a fraction whose denominator
|
||||
/// is 256. In other words, it computes i * (scale / 256)
|
||||
|
||||
LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8( uint16_t i, fract8 scale )
|
||||
{
|
||||
#if SCALE16BY8_C == 1
|
||||
uint16_t result;
|
||||
#if FASTLED_SCALE8_FIXED == 1
|
||||
result = (i * (1+((uint16_t)scale))) >> 8;
|
||||
#else
|
||||
result = (i * scale) / 256;
|
||||
#endif
|
||||
return result;
|
||||
#elif SCALE16BY8_AVRASM == 1
|
||||
#if FASTLED_SCALE8_FIXED == 1
|
||||
uint16_t result = 0;
|
||||
asm volatile(
|
||||
// result.A = HighByte( (i.A x scale) + i.A )
|
||||
" mul %A[i], %[scale] \n\t"
|
||||
" add r0, %A[i] \n\t"
|
||||
// " adc r1, [zero] \n\t"
|
||||
// " mov %A[result], r1 \n\t"
|
||||
" adc %A[result], r1 \n\t"
|
||||
|
||||
// result.A-B += i.B x scale
|
||||
" mul %B[i], %[scale] \n\t"
|
||||
" add %A[result], r0 \n\t"
|
||||
" adc %B[result], r1 \n\t"
|
||||
|
||||
// cleanup r1
|
||||
" clr __zero_reg__ \n\t"
|
||||
|
||||
// result.A-B += i.B
|
||||
" add %A[result], %B[i] \n\t"
|
||||
" adc %B[result], __zero_reg__ \n\t"
|
||||
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i), [scale] "r" (scale)
|
||||
: "r0", "r1"
|
||||
);
|
||||
return result;
|
||||
#else
|
||||
uint16_t result = 0;
|
||||
asm volatile(
|
||||
// result.A = HighByte(i.A x j )
|
||||
" mul %A[i], %[scale] \n\t"
|
||||
" mov %A[result], r1 \n\t"
|
||||
//" clr %B[result] \n\t"
|
||||
|
||||
// result.A-B += i.B x j
|
||||
" mul %B[i], %[scale] \n\t"
|
||||
" add %A[result], r0 \n\t"
|
||||
" adc %B[result], r1 \n\t"
|
||||
|
||||
// cleanup r1
|
||||
" clr __zero_reg__ \n\t"
|
||||
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i), [scale] "r" (scale)
|
||||
: "r0", "r1"
|
||||
);
|
||||
return result;
|
||||
#endif
|
||||
#else
|
||||
#error "No implementation for scale16by8 available."
|
||||
#endif
|
||||
}
|
||||
|
||||
/// scale a 16-bit unsigned value by a 16-bit value,
|
||||
/// considered as numerator of a fraction whose denominator
|
||||
/// is 65536. In other words, it computes i * (scale / 65536)
|
||||
|
||||
LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale )
|
||||
{
|
||||
#if SCALE16_C == 1
|
||||
uint16_t result;
|
||||
#if FASTLED_SCALE8_FIXED == 1
|
||||
result = ((uint32_t)(i) * (1+(uint32_t)(scale))) / 65536;
|
||||
#else
|
||||
result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
|
||||
#endif
|
||||
return result;
|
||||
#elif SCALE16_AVRASM == 1
|
||||
#if FASTLED_SCALE8_FIXED == 1
|
||||
// implemented sort of like
|
||||
// result = ((i * scale) + i ) / 65536
|
||||
//
|
||||
// why not like this, you may ask?
|
||||
// result = (i * (scale+1)) / 65536
|
||||
// the answer is that if scale is 65535, then scale+1
|
||||
// will be zero, which is not what we want.
|
||||
uint32_t result;
|
||||
asm volatile(
|
||||
// result.A-B = i.A x scale.A
|
||||
" mul %A[i], %A[scale] \n\t"
|
||||
// save results...
|
||||
// basic idea:
|
||||
//" mov %A[result], r0 \n\t"
|
||||
//" mov %B[result], r1 \n\t"
|
||||
// which can be written as...
|
||||
" movw %A[result], r0 \n\t"
|
||||
// Because we're going to add i.A-B to
|
||||
// result.A-D, we DO need to keep both
|
||||
// the r0 and r1 portions of the product
|
||||
// UNlike in the 'unfixed scale8' version.
|
||||
// So the movw here is needed.
|
||||
: [result] "=r" (result)
|
||||
: [i] "r" (i),
|
||||
[scale] "r" (scale)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
asm volatile(
|
||||
// result.C-D = i.B x scale.B
|
||||
" mul %B[i], %B[scale] \n\t"
|
||||
//" mov %C[result], r0 \n\t"
|
||||
//" mov %D[result], r1 \n\t"
|
||||
" movw %C[result], r0 \n\t"
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i),
|
||||
[scale] "r" (scale)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
const uint8_t zero = 0;
|
||||
asm volatile(
|
||||
// result.B-D += i.B x scale.A
|
||||
" mul %B[i], %A[scale] \n\t"
|
||||
|
||||
" add %B[result], r0 \n\t"
|
||||
" adc %C[result], r1 \n\t"
|
||||
" adc %D[result], %[zero] \n\t"
|
||||
|
||||
// result.B-D += i.A x scale.B
|
||||
" mul %A[i], %B[scale] \n\t"
|
||||
|
||||
" add %B[result], r0 \n\t"
|
||||
" adc %C[result], r1 \n\t"
|
||||
" adc %D[result], %[zero] \n\t"
|
||||
|
||||
// cleanup r1
|
||||
" clr r1 \n\t"
|
||||
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i),
|
||||
[scale] "r" (scale),
|
||||
[zero] "r" (zero)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
asm volatile(
|
||||
// result.A-D += i.A-B
|
||||
" add %A[result], %A[i] \n\t"
|
||||
" adc %B[result], %B[i] \n\t"
|
||||
" adc %C[result], %[zero] \n\t"
|
||||
" adc %D[result], %[zero] \n\t"
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i),
|
||||
[zero] "r" (zero)
|
||||
);
|
||||
|
||||
result = result >> 16;
|
||||
return result;
|
||||
#else
|
||||
uint32_t result;
|
||||
asm volatile(
|
||||
// result.A-B = i.A x scale.A
|
||||
" mul %A[i], %A[scale] \n\t"
|
||||
// save results...
|
||||
// basic idea:
|
||||
//" mov %A[result], r0 \n\t"
|
||||
//" mov %B[result], r1 \n\t"
|
||||
// which can be written as...
|
||||
" movw %A[result], r0 \n\t"
|
||||
// We actually don't need to do anything with r0,
|
||||
// as result.A is never used again here, so we
|
||||
// could just move the high byte, but movw is
|
||||
// one clock cycle, just like mov, so might as
|
||||
// well, in case we want to use this code for
|
||||
// a generic 16x16 multiply somewhere.
|
||||
|
||||
: [result] "=r" (result)
|
||||
: [i] "r" (i),
|
||||
[scale] "r" (scale)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
asm volatile(
|
||||
// result.C-D = i.B x scale.B
|
||||
" mul %B[i], %B[scale] \n\t"
|
||||
//" mov %C[result], r0 \n\t"
|
||||
//" mov %D[result], r1 \n\t"
|
||||
" movw %C[result], r0 \n\t"
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i),
|
||||
[scale] "r" (scale)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
const uint8_t zero = 0;
|
||||
asm volatile(
|
||||
// result.B-D += i.B x scale.A
|
||||
" mul %B[i], %A[scale] \n\t"
|
||||
|
||||
" add %B[result], r0 \n\t"
|
||||
" adc %C[result], r1 \n\t"
|
||||
" adc %D[result], %[zero] \n\t"
|
||||
|
||||
// result.B-D += i.A x scale.B
|
||||
" mul %A[i], %B[scale] \n\t"
|
||||
|
||||
" add %B[result], r0 \n\t"
|
||||
" adc %C[result], r1 \n\t"
|
||||
" adc %D[result], %[zero] \n\t"
|
||||
|
||||
// cleanup r1
|
||||
" clr r1 \n\t"
|
||||
|
||||
: [result] "+r" (result)
|
||||
: [i] "r" (i),
|
||||
[scale] "r" (scale),
|
||||
[zero] "r" (zero)
|
||||
: "r0", "r1"
|
||||
);
|
||||
|
||||
result = result >> 16;
|
||||
return result;
|
||||
#endif
|
||||
#else
|
||||
#error "No implementation for scale16 available."
|
||||
#endif
|
||||
}
|
||||
///@}
|
||||
|
||||
///@defgroup Dimming Dimming and brightening functions
|
||||
///
|
||||
/// Dimming and brightening functions
|
||||
///
|
||||
/// The eye does not respond in a linear way to light.
|
||||
/// High speed PWM'd LEDs at 50% duty cycle appear far
|
||||
/// brighter then the 'half as bright' you might expect.
|
||||
///
|
||||
/// If you want your midpoint brightness leve (128) to
|
||||
/// appear half as bright as 'full' brightness (255), you
|
||||
/// have to apply a 'dimming function'.
|
||||
///@{
|
||||
|
||||
/// Adjust a scaling value for dimming
|
||||
LIB8STATIC uint8_t dim8_raw( uint8_t x)
|
||||
{
|
||||
return scale8( x, x);
|
||||
}
|
||||
|
||||
/// Adjust a scaling value for dimming for video (value will never go below 1)
|
||||
LIB8STATIC uint8_t dim8_video( uint8_t x)
|
||||
{
|
||||
return scale8_video( x, x);
|
||||
}
|
||||
|
||||
/// Linear version of the dimming function that halves for values < 128
|
||||
LIB8STATIC uint8_t dim8_lin( uint8_t x )
|
||||
{
|
||||
if( x & 0x80 ) {
|
||||
x = scale8( x, x);
|
||||
} else {
|
||||
x += 1;
|
||||
x /= 2;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/// inverse of the dimming function, brighten a value
|
||||
LIB8STATIC uint8_t brighten8_raw( uint8_t x)
|
||||
{
|
||||
uint8_t ix = 255 - x;
|
||||
return 255 - scale8( ix, ix);
|
||||
}
|
||||
|
||||
/// inverse of the dimming function, brighten a value
|
||||
LIB8STATIC uint8_t brighten8_video( uint8_t x)
|
||||
{
|
||||
uint8_t ix = 255 - x;
|
||||
return 255 - scale8_video( ix, ix);
|
||||
}
|
||||
|
||||
/// inverse of the dimming function, brighten a value
|
||||
LIB8STATIC uint8_t brighten8_lin( uint8_t x )
|
||||
{
|
||||
uint8_t ix = 255 - x;
|
||||
if( ix & 0x80 ) {
|
||||
ix = scale8( ix, ix);
|
||||
} else {
|
||||
ix += 1;
|
||||
ix /= 2;
|
||||
}
|
||||
return 255 - ix;
|
||||
}
|
||||
|
||||
///@}
|
||||
#endif
|
@ -0,0 +1,259 @@
|
||||
#ifndef __INC_LIB8TION_TRIG_H
|
||||
#define __INC_LIB8TION_TRIG_H
|
||||
|
||||
///@ingroup lib8tion
|
||||
|
||||
///@defgroup Trig Fast trig functions
|
||||
/// Fast 8 and 16-bit approximations of sin(x) and cos(x).
|
||||
/// Don't use these approximations for calculating the
|
||||
/// trajectory of a rocket to Mars, but they're great
|
||||
/// for art projects and LED displays.
|
||||
///
|
||||
/// On Arduino/AVR, the 16-bit approximation is more than
|
||||
/// 10X faster than floating point sin(x) and cos(x), while
|
||||
/// the 8-bit approximation is more than 20X faster.
|
||||
///@{
|
||||
|
||||
#if defined(__AVR__)
|
||||
#define sin16 sin16_avr
|
||||
#else
|
||||
#define sin16 sin16_C
|
||||
#endif
|
||||
|
||||
/// Fast 16-bit approximation of sin(x). This approximation never varies more than
|
||||
/// 0.69% from the floating point value you'd get by doing
|
||||
///
|
||||
/// float s = sin(x) * 32767.0;
|
||||
///
|
||||
/// @param theta input angle from 0-65535
|
||||
/// @returns sin of theta, value between -32767 to 32767.
|
||||
LIB8STATIC int16_t sin16_avr( uint16_t theta )
|
||||
{
|
||||
static const uint8_t data[] =
|
||||
{ 0, 0, 49, 0, 6393%256, 6393/256, 48, 0,
|
||||
12539%256, 12539/256, 44, 0, 18204%256, 18204/256, 38, 0,
|
||||
23170%256, 23170/256, 31, 0, 27245%256, 27245/256, 23, 0,
|
||||
30273%256, 30273/256, 14, 0, 32137%256, 32137/256, 4 /*,0*/ };
|
||||
|
||||
uint16_t offset = (theta & 0x3FFF);
|
||||
|
||||
// AVR doesn't have a multi-bit shift instruction,
|
||||
// so if we say "offset >>= 3", gcc makes a tiny loop.
|
||||
// Inserting empty volatile statements between each
|
||||
// bit shift forces gcc to unroll the loop.
|
||||
offset >>= 1; // 0..8191
|
||||
asm volatile("");
|
||||
offset >>= 1; // 0..4095
|
||||
asm volatile("");
|
||||
offset >>= 1; // 0..2047
|
||||
|
||||
if( theta & 0x4000 ) offset = 2047 - offset;
|
||||
|
||||
uint8_t sectionX4;
|
||||
sectionX4 = offset / 256;
|
||||
sectionX4 *= 4;
|
||||
|
||||
uint8_t m;
|
||||
|
||||
union {
|
||||
uint16_t b;
|
||||
struct {
|
||||
uint8_t blo;
|
||||
uint8_t bhi;
|
||||
};
|
||||
} u;
|
||||
|
||||
//in effect u.b = blo + (256 * bhi);
|
||||
u.blo = data[ sectionX4 ];
|
||||
u.bhi = data[ sectionX4 + 1];
|
||||
m = data[ sectionX4 + 2];
|
||||
|
||||
uint8_t secoffset8 = (uint8_t)(offset) / 2;
|
||||
|
||||
uint16_t mx = m * secoffset8;
|
||||
|
||||
int16_t y = mx + u.b;
|
||||
if( theta & 0x8000 ) y = -y;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/// Fast 16-bit approximation of sin(x). This approximation never varies more than
|
||||
/// 0.69% from the floating point value you'd get by doing
|
||||
///
|
||||
/// float s = sin(x) * 32767.0;
|
||||
///
|
||||
/// @param theta input angle from 0-65535
|
||||
/// @returns sin of theta, value between -32767 to 32767.
|
||||
LIB8STATIC int16_t sin16_C( uint16_t theta )
|
||||
{
|
||||
static const uint16_t base[] =
|
||||
{ 0, 6393, 12539, 18204, 23170, 27245, 30273, 32137 };
|
||||
static const uint8_t slope[] =
|
||||
{ 49, 48, 44, 38, 31, 23, 14, 4 };
|
||||
|
||||
uint16_t offset = (theta & 0x3FFF) >> 3; // 0..2047
|
||||
if( theta & 0x4000 ) offset = 2047 - offset;
|
||||
|
||||
uint8_t section = offset / 256; // 0..7
|
||||
uint16_t b = base[section];
|
||||
uint8_t m = slope[section];
|
||||
|
||||
uint8_t secoffset8 = (uint8_t)(offset) / 2;
|
||||
|
||||
uint16_t mx = m * secoffset8;
|
||||
int16_t y = mx + b;
|
||||
|
||||
if( theta & 0x8000 ) y = -y;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/// Fast 16-bit approximation of cos(x). This approximation never varies more than
|
||||
/// 0.69% from the floating point value you'd get by doing
|
||||
///
|
||||
/// float s = cos(x) * 32767.0;
|
||||
///
|
||||
/// @param theta input angle from 0-65535
|
||||
/// @returns sin of theta, value between -32767 to 32767.
|
||||
LIB8STATIC int16_t cos16( uint16_t theta)
|
||||
{
|
||||
return sin16( theta + 16384);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
// sin8 & cos8
|
||||
// Fast 8-bit approximations of sin(x) & cos(x).
|
||||
// Input angle is an unsigned int from 0-255.
|
||||
// Output is an unsigned int from 0 to 255.
|
||||
//
|
||||
// This approximation can vary to to 2%
|
||||
// from the floating point value you'd get by doing
|
||||
// float s = (sin( x ) * 128.0) + 128;
|
||||
//
|
||||
// Don't use this approximation for calculating the
|
||||
// "real" trigonometric calculations, but it's great
|
||||
// for art projects and LED displays.
|
||||
//
|
||||
// On Arduino/AVR, this approximation is more than
|
||||
// 20X faster than floating point sin(x) and cos(x)
|
||||
|
||||
#if defined(__AVR__) && !defined(LIB8_ATTINY)
|
||||
#define sin8 sin8_avr
|
||||
#else
|
||||
#define sin8 sin8_C
|
||||
#endif
|
||||
|
||||
|
||||
const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 };
|
||||
|
||||
/// Fast 8-bit approximation of sin(x). This approximation never varies more than
|
||||
/// 2% from the floating point value you'd get by doing
|
||||
///
|
||||
/// float s = (sin(x) * 128.0) + 128;
|
||||
///
|
||||
/// @param theta input angle from 0-255
|
||||
/// @returns sin of theta, value between 0 and 255
|
||||
LIB8STATIC uint8_t sin8_avr( uint8_t theta)
|
||||
{
|
||||
uint8_t offset = theta;
|
||||
|
||||
asm volatile(
|
||||
"sbrc %[theta],6 \n\t"
|
||||
"com %[offset] \n\t"
|
||||
: [theta] "+r" (theta), [offset] "+r" (offset)
|
||||
);
|
||||
|
||||
offset &= 0x3F; // 0..63
|
||||
|
||||
uint8_t secoffset = offset & 0x0F; // 0..15
|
||||
if( theta & 0x40) secoffset++;
|
||||
|
||||
uint8_t m16; uint8_t b;
|
||||
|
||||
uint8_t section = offset >> 4; // 0..3
|
||||
uint8_t s2 = section * 2;
|
||||
|
||||
const uint8_t* p = b_m16_interleave;
|
||||
p += s2;
|
||||
b = *p;
|
||||
p++;
|
||||
m16 = *p;
|
||||
|
||||
uint8_t mx;
|
||||
uint8_t xr1;
|
||||
asm volatile(
|
||||
"mul %[m16],%[secoffset] \n\t"
|
||||
"mov %[mx],r0 \n\t"
|
||||
"mov %[xr1],r1 \n\t"
|
||||
"eor r1, r1 \n\t"
|
||||
"swap %[mx] \n\t"
|
||||
"andi %[mx],0x0F \n\t"
|
||||
"swap %[xr1] \n\t"
|
||||
"andi %[xr1], 0xF0 \n\t"
|
||||
"or %[mx], %[xr1] \n\t"
|
||||
: [mx] "=d" (mx), [xr1] "=d" (xr1)
|
||||
: [m16] "d" (m16), [secoffset] "d" (secoffset)
|
||||
);
|
||||
|
||||
int8_t y = mx + b;
|
||||
if( theta & 0x80 ) y = -y;
|
||||
|
||||
y += 128;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/// Fast 8-bit approximation of sin(x). This approximation never varies more than
|
||||
/// 2% from the floating point value you'd get by doing
|
||||
///
|
||||
/// float s = (sin(x) * 128.0) + 128;
|
||||
///
|
||||
/// @param theta input angle from 0-255
|
||||
/// @returns sin of theta, value between 0 and 255
|
||||
LIB8STATIC uint8_t sin8_C( uint8_t theta)
|
||||
{
|
||||
uint8_t offset = theta;
|
||||
if( theta & 0x40 ) {
|
||||
offset = (uint8_t)255 - offset;
|
||||
}
|
||||
offset &= 0x3F; // 0..63
|
||||
|
||||
uint8_t secoffset = offset & 0x0F; // 0..15
|
||||
if( theta & 0x40) secoffset++;
|
||||
|
||||
uint8_t section = offset >> 4; // 0..3
|
||||
uint8_t s2 = section * 2;
|
||||
const uint8_t* p = b_m16_interleave;
|
||||
p += s2;
|
||||
uint8_t b = *p;
|
||||
p++;
|
||||
uint8_t m16 = *p;
|
||||
|
||||
uint8_t mx = (m16 * secoffset) >> 4;
|
||||
|
||||
int8_t y = mx + b;
|
||||
if( theta & 0x80 ) y = -y;
|
||||
|
||||
y += 128;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/// Fast 8-bit approximation of cos(x). This approximation never varies more than
|
||||
/// 2% from the floating point value you'd get by doing
|
||||
///
|
||||
/// float s = (cos(x) * 128.0) + 128;
|
||||
///
|
||||
/// @param theta input angle from 0-255
|
||||
/// @returns sin of theta, value between 0 and 255
|
||||
LIB8STATIC uint8_t cos8( uint8_t theta)
|
||||
{
|
||||
return sin8( theta + 64);
|
||||
}
|
||||
|
||||
///@}
|
||||
#endif
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright 2019 Alex Ong<the.onga@gmail.com>
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Basic per-row algorithm. Uses an 8-bit counter per row.
|
||||
After pressing a key, it immediately changes state, and sets a counter.
|
||||
No further inputs are accepted until DEBOUNCE milliseconds have occurred.
|
||||
*/
|
||||
|
||||
#include "matrix.h"
|
||||
#include "timer.h"
|
||||
#include "quantum.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
#define DEBOUNCE 5
|
||||
#endif
|
||||
|
||||
|
||||
#define debounce_counter_t uint8_t
|
||||
|
||||
static debounce_counter_t *debounce_counters;
|
||||
|
||||
#define DEBOUNCE_ELAPSED 251
|
||||
#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
|
||||
|
||||
void update_debounce_counters(uint8_t num_rows, uint8_t current_time);
|
||||
void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
|
||||
|
||||
//we use num_rows rather than MATRIX_ROWS to support split keyboards
|
||||
void debounce_init(uint8_t num_rows)
|
||||
{
|
||||
debounce_counters = (debounce_counter_t*)malloc(num_rows*sizeof(debounce_counter_t));
|
||||
for (uint8_t r = 0; r < num_rows; r++)
|
||||
{
|
||||
debounce_counters[r] = DEBOUNCE_ELAPSED;
|
||||
}
|
||||
}
|
||||
|
||||
void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed)
|
||||
{
|
||||
uint8_t current_time = timer_read() % MAX_DEBOUNCE;
|
||||
update_debounce_counters(num_rows, current_time);
|
||||
transfer_matrix_values(raw, cooked, num_rows, current_time);
|
||||
}
|
||||
|
||||
//If the current time is > debounce counter, set the counter to enable input.
|
||||
void update_debounce_counters(uint8_t num_rows, uint8_t current_time)
|
||||
{
|
||||
debounce_counter_t *debounce_pointer = debounce_counters;
|
||||
for (uint8_t row = 0; row < num_rows; row++)
|
||||
{
|
||||
if (*debounce_pointer != DEBOUNCE_ELAPSED)
|
||||
{
|
||||
if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) {
|
||||
*debounce_pointer = DEBOUNCE_ELAPSED;
|
||||
}
|
||||
}
|
||||
debounce_pointer++;
|
||||
}
|
||||
}
|
||||
|
||||
// upload from raw_matrix to final matrix;
|
||||
void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time)
|
||||
{
|
||||
debounce_counter_t *debounce_pointer = debounce_counters;
|
||||
for (uint8_t row = 0; row < num_rows; row++)
|
||||
{
|
||||
matrix_row_t existing_row = cooked[row];
|
||||
matrix_row_t raw_row = raw[row];
|
||||
|
||||
//determine new value basd on debounce pointer + raw value
|
||||
if (*debounce_pointer == DEBOUNCE_ELAPSED &&
|
||||
(existing_row != raw_row))
|
||||
{
|
||||
*debounce_pointer = current_time;
|
||||
existing_row = raw_row;
|
||||
}
|
||||
cooked[row] = existing_row;
|
||||
|
||||
debounce_pointer++;
|
||||
}
|
||||
}
|
||||
|
||||
bool debounce_active(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS
|
||||
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
// alphas = color1, mods = color2
|
||||
bool rgb_matrix_alphas_mods(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
RGB rgb1 = hsv_to_rgb(hsv);
|
||||
hsv.h += rgb_matrix_config.speed;
|
||||
RGB rgb2 = hsv_to_rgb(hsv);
|
||||
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
if (g_rgb_leds[i].modifier) {
|
||||
rgb_matrix_set_color(i, rgb2.r, rgb2.g, rgb2.b);
|
||||
} else {
|
||||
rgb_matrix_set_color(i, rgb1.r, rgb1.g, rgb1.b);
|
||||
}
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_ALPHAS_MODS
|
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_BREATHING
|
||||
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_breathing(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 8);
|
||||
uint8_t val = scale8(abs8(sin8(time) - 128) * 2, rgb_matrix_config.val);
|
||||
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, val };
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_BREATHING
|
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_cycle_all(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
hsv.h = time;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_CYCLE_ALL
|
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_cycle_left_right(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
hsv.h = point.x - time;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
|
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_cycle_up_down(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
hsv.h = point.y - time;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
|
@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
|
||||
|
||||
#ifndef RGB_DIGITAL_RAIN_DROPS
|
||||
// lower the number for denser effect/wider keyboard
|
||||
#define RGB_DIGITAL_RAIN_DROPS 24
|
||||
#endif
|
||||
|
||||
bool rgb_matrix_digital_rain(effect_params_t* params) {
|
||||
// algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain
|
||||
const uint8_t drop_ticks = 28;
|
||||
const uint8_t pure_green_intensity = 0xd0;
|
||||
const uint8_t max_brightness_boost = 0xc0;
|
||||
const uint8_t max_intensity = 0xff;
|
||||
|
||||
static uint8_t map[MATRIX_COLS][MATRIX_ROWS] = {{0}};
|
||||
static uint8_t drop = 0;
|
||||
|
||||
if (params->init) {
|
||||
rgb_matrix_set_color_all(0, 0, 0);
|
||||
memset(map, 0, sizeof map);
|
||||
drop = 0;
|
||||
}
|
||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
|
||||
// top row, pixels have just fallen and we're
|
||||
// making a new rain drop in this column
|
||||
map[col][row] = max_intensity;
|
||||
}
|
||||
else if (map[col][row] > 0 && map[col][row] < max_intensity) {
|
||||
// neither fully bright nor dark, decay it
|
||||
map[col][row]--;
|
||||
}
|
||||
// set the pixel colour
|
||||
uint8_t led[LED_HITS_TO_REMEMBER];
|
||||
uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
|
||||
|
||||
// TODO: multiple leds are supported mapped to the same row/column
|
||||
if (led_count > 0) {
|
||||
if (map[col][row] > pure_green_intensity) {
|
||||
const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost * (map[col][row] - pure_green_intensity) / (max_intensity - pure_green_intensity));
|
||||
rgb_matrix_set_color(led[0], boost, max_intensity, boost);
|
||||
}
|
||||
else {
|
||||
const uint8_t green = (uint8_t) ((uint16_t) max_intensity * map[col][row] / pure_green_intensity);
|
||||
rgb_matrix_set_color(led[0], 0, green, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (++drop > drop_ticks) {
|
||||
// reset drop timer
|
||||
drop = 0;
|
||||
for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
|
||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
|
||||
// if ths is on the bottom row and bright allow decay
|
||||
if (row == MATRIX_ROWS - 1 && map[col][row] == max_intensity) {
|
||||
map[col][row]--;
|
||||
}
|
||||
// check if the pixel above is bright
|
||||
if (map[col][row - 1] == max_intensity) {
|
||||
// allow old bright pixel to decay
|
||||
map[col][row - 1]--;
|
||||
// make this pixel bright
|
||||
map[col][row] = max_intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN
|
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_dual_beacon(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
int8_t cos_value = cos8(time) - 128;
|
||||
int8_t sin_value = sin8(time) - 128;
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
hsv.h = ((point.y - 32) * cos_value + (point.x - 112) * sin_value) / 128 + rgb_matrix_config.hue;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_DUAL_BEACON
|
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
|
||||
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_gradient_up_down(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint8_t scale = scale8(64, rgb_matrix_config.speed);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
// The y range will be 0..64, map this to 0..4
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
hsv.h = rgb_matrix_config.hue + scale * (point.y >> 4);
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
#endif // DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
|
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
static void jellybean_raindrops_set_color(int i) {
|
||||
HSV hsv = { rand() & 0xFF , rand() & 0xFF, rgb_matrix_config.val };
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
|
||||
bool rgb_matrix_jellybean_raindrops(effect_params_t* params) {
|
||||
if (!params->init) {
|
||||
// Change one LED every tick, make sure speed is not 0
|
||||
if (scale16by8(g_rgb_counters.tick, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) {
|
||||
jellybean_raindrops_set_color(rand() % DRIVER_LED_TOTAL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
for (int i = led_min; i < led_max; i++) {
|
||||
jellybean_raindrops_set_color(i);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
|
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_rainbow_beacon(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
int16_t cos_value = 2 * (cos8(time) - 128);
|
||||
int16_t sin_value = 2 * (sin8(time) - 128);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
hsv.h = ((point.y - 32) * cos_value + (point.x - 112) * sin_value) / 128 + rgb_matrix_config.hue;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_RAINBOW_BEACON
|
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_rainbow_moving_chevron(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
hsv.h = abs8(point.y - 32) + (point.x - time) + rgb_matrix_config.hue;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
|
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_rainbow_pinwheels(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
|
||||
int16_t cos_value = 3 * (cos8(time) - 128);
|
||||
int16_t sin_value = 3 * (sin8(time) - 128);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
hsv.h = ((point.y - 32) * cos_value + (56 - abs8(point.x - 112)) * sin_value) / 128 + rgb_matrix_config.hue;
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
|
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#ifndef DISABLE_RGB_MATRIX_RAINDROPS
|
||||
#include "rgb_matrix_types.h"
|
||||
|
||||
extern rgb_counters_t g_rgb_counters;
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
static void raindrops_set_color(int i) {
|
||||
HSV hsv = { 0 , rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
|
||||
// Take the shortest path between hues
|
||||
int16_t deltaH = ((rgb_matrix_config.hue + 180) % 360 - rgb_matrix_config.hue) / 4;
|
||||
if (deltaH > 127) {
|
||||
deltaH -= 256;
|
||||
} else if (deltaH < -127) {
|
||||
deltaH += 256;
|
||||
}
|
||||
|
||||
hsv.h = rgb_matrix_config.hue + (deltaH * (rand() & 0x03));
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
|
||||
bool rgb_matrix_raindrops(effect_params_t* params) {
|
||||
if (!params->init) {
|
||||
// Change one LED every tick, make sure speed is not 0
|
||||
if (scale16by8(g_rgb_counters.tick, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) {
|
||||
raindrops_set_color(rand() % DRIVER_LED_TOTAL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
for (int i = led_min; i < led_max; i++) {
|
||||
raindrops_set_color(i);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_RAINDROPS
|
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
|
||||
bool rgb_matrix_solid_color(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, rgb_matrix_config.val };
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
|
||||
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
|
||||
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
extern last_hit_t g_last_hit_tracker;
|
||||
|
||||
bool rgb_matrix_solid_reactive(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { rgb_matrix_config.hue, 255, rgb_matrix_config.val };
|
||||
// Max tick based on speed scale ensures results from scale16by8 with rgb_matrix_config.speed are no greater than 255
|
||||
uint16_t max_tick = 65535 / rgb_matrix_config.speed;
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
uint16_t tick = max_tick;
|
||||
for(uint8_t j = 0; j < g_last_hit_tracker.count; j++) {
|
||||
if (g_last_hit_tracker.index[j] == i && g_last_hit_tracker.tick[j] < tick) {
|
||||
tick = g_last_hit_tracker.tick[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t offset = scale16by8(tick, rgb_matrix_config.speed);
|
||||
hsv.h = rgb_matrix_config.hue + qsub8(130, offset);
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
|
||||
#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
|
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
|
||||
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
|
||||
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
extern last_hit_t g_last_hit_tracker;
|
||||
|
||||
bool rgb_matrix_solid_reactive_simple(effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
|
||||
// Max tick based on speed scale ensures results from scale16by8 with rgb_matrix_config.speed are no greater than 255
|
||||
uint16_t max_tick = 65535 / rgb_matrix_config.speed;
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
uint16_t tick = max_tick;
|
||||
for(uint8_t j = 0; j < g_last_hit_tracker.count; j++) {
|
||||
if (g_last_hit_tracker.index[j] == i && g_last_hit_tracker.tick[j] < tick) {
|
||||
tick = g_last_hit_tracker.tick[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t offset = scale16by8(tick, rgb_matrix_config.speed);
|
||||
hsv.v = scale8(255 - offset, rgb_matrix_config.val);
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
|
||||
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
|
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
|
||||
#if !defined(DISABLE_RGB_MATRIX_SOLID_SPLASH) || !defined(DISABLE_RGB_MATRIX_SOLID_MULTISPLASH)
|
||||
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
extern last_hit_t g_last_hit_tracker;
|
||||
|
||||
static bool rgb_matrix_solid_multisplash_range(uint8_t start, effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, 0 };
|
||||
uint8_t count = g_last_hit_tracker.count;
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
hsv.v = 0;
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
for (uint8_t j = start; j < count; j++) {
|
||||
int16_t dx = point.x - g_last_hit_tracker.x[j];
|
||||
int16_t dy = point.y - g_last_hit_tracker.y[j];
|
||||
uint8_t dist = sqrt16(dx * dx + dy * dy);
|
||||
uint16_t effect = scale16by8(g_last_hit_tracker.tick[j], rgb_matrix_config.speed) - dist;
|
||||
if (effect > 255)
|
||||
effect = 255;
|
||||
hsv.v = qadd8(hsv.v, 255 - effect);
|
||||
}
|
||||
hsv.v = scale8(hsv.v, rgb_matrix_config.val);
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
bool rgb_matrix_solid_multisplash(effect_params_t* params) {
|
||||
return rgb_matrix_solid_multisplash_range(0, params);
|
||||
}
|
||||
|
||||
bool rgb_matrix_solid_splash(effect_params_t* params) {
|
||||
return rgb_matrix_solid_multisplash_range(qsub8(g_last_hit_tracker.count, 1), params);
|
||||
}
|
||||
|
||||
#endif // !defined(DISABLE_RGB_MATRIX_SPLASH) && !defined(DISABLE_RGB_MATRIX_MULTISPLASH)
|
||||
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
|
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
|
||||
#if !defined(DISABLE_RGB_MATRIX_SPLASH) || !defined(DISABLE_RGB_MATRIX_MULTISPLASH)
|
||||
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
extern rgb_config_t rgb_matrix_config;
|
||||
extern last_hit_t g_last_hit_tracker;
|
||||
|
||||
static bool rgb_matrix_multisplash_range(uint8_t start, effect_params_t* params) {
|
||||
RGB_MATRIX_USE_LIMITS(led_min, led_max);
|
||||
|
||||
HSV hsv = { 0, rgb_matrix_config.sat, 0 };
|
||||
uint8_t count = g_last_hit_tracker.count;
|
||||
for (uint8_t i = led_min; i < led_max; i++) {
|
||||
hsv.h = rgb_matrix_config.hue;
|
||||
hsv.v = 0;
|
||||
point_t point = g_rgb_leds[i].point;
|
||||
for (uint8_t j = start; j < count; j++) {
|
||||
int16_t dx = point.x - g_last_hit_tracker.x[j];
|
||||
int16_t dy = point.y - g_last_hit_tracker.y[j];
|
||||
uint8_t dist = sqrt16(dx * dx + dy * dy);
|
||||
uint16_t effect = scale16by8(g_last_hit_tracker.tick[j], rgb_matrix_config.speed) - dist;
|
||||
if (effect > 255)
|
||||
effect = 255;
|
||||
hsv.h += effect;
|
||||
hsv.v = qadd8(hsv.v, 255 - effect);
|
||||
}
|
||||
hsv.v = scale8(hsv.v, rgb_matrix_config.val);
|
||||
RGB rgb = hsv_to_rgb(hsv);
|
||||
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
|
||||
}
|
||||
return led_max < DRIVER_LED_TOTAL;
|
||||
}
|
||||
|
||||
bool rgb_matrix_multisplash(effect_params_t* params) {
|
||||
return rgb_matrix_multisplash_range(0, params);
|
||||
}
|
||||
|
||||
bool rgb_matrix_splash(effect_params_t* params) {
|
||||
return rgb_matrix_multisplash_range(qsub8(g_last_hit_tracker.count, 1), params);
|
||||
}
|
||||
|
||||
#endif // !defined(DISABLE_RGB_MATRIX_SPLASH) || !defined(DISABLE_RGB_MATRIX_MULTISPLASH)
|
||||
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
|
@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define PACKED __attribute__ ((__packed__))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack( push, 1 )
|
||||
#endif
|
||||
|
||||
#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES)
|
||||
#define RGB_MATRIX_KEYREACTIVE_ENABLED
|
||||
#endif
|
||||
|
||||
// Last led hit
|
||||
#ifndef LED_HITS_TO_REMEMBER
|
||||
#define LED_HITS_TO_REMEMBER 8
|
||||
#endif // LED_HITS_TO_REMEMBER
|
||||
|
||||
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
|
||||
typedef struct PACKED {
|
||||
uint8_t count;
|
||||
uint8_t x[LED_HITS_TO_REMEMBER];
|
||||
uint8_t y[LED_HITS_TO_REMEMBER];
|
||||
uint8_t index[LED_HITS_TO_REMEMBER];
|
||||
uint16_t tick[LED_HITS_TO_REMEMBER];
|
||||
} last_hit_t;
|
||||
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
|
||||
|
||||
typedef enum rgb_task_states {
|
||||
STARTING,
|
||||
RENDERING,
|
||||
FLUSHING,
|
||||
SYNCING
|
||||
} rgb_task_states;
|
||||
|
||||
typedef uint8_t led_flags_t;
|
||||
|
||||
typedef struct PACKED {
|
||||
uint8_t iter;
|
||||
led_flags_t flags;
|
||||
bool init;
|
||||
} effect_params_t;
|
||||
|
||||
typedef struct PACKED {
|
||||
// Global tick at 20 Hz
|
||||
uint32_t tick;
|
||||
// Ticks since this key was last hit.
|
||||
uint32_t any_key_hit;
|
||||
} rgb_counters_t;
|
||||
|
||||
typedef struct PACKED {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} point_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t raw;
|
||||
struct {
|
||||
uint8_t row:4; // 16 max
|
||||
uint8_t col:4; // 16 max
|
||||
};
|
||||
} matrix_co_t;
|
||||
|
||||
typedef struct PACKED {
|
||||
matrix_co_t matrix_co;
|
||||
point_t point;
|
||||
uint8_t modifier:1;
|
||||
} rgb_led;
|
||||
|
||||
typedef enum {
|
||||
RGB_ZONE_OFF = 0,
|
||||
RGB_ZONE_ALL,
|
||||
RGB_ZONE_KEYS,
|
||||
RGB_ZONE_UNDER,
|
||||
} rgb_zone_t;
|
||||
|
||||
typedef union {
|
||||
uint32_t raw;
|
||||
struct PACKED {
|
||||
uint8_t enable :2;
|
||||
uint8_t mode :6;
|
||||
uint8_t hue :8;
|
||||
uint8_t sat :8;
|
||||
uint8_t val :8;
|
||||
uint8_t speed :8;//EECONFIG needs to be increased to support this
|
||||
};
|
||||
} rgb_config_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack( pop )
|
||||
#endif
|
Loading…
Reference in new issue