Compare commits

...

3 Commits

Author SHA1 Message Date
22789a4409 Update keyboards/subatomic/config.h
Co-Authored-By: James Young <18669334+noroadsleft@users.noreply.github.com>
2019-11-04 21:40:11 -05:00
dbae55e2ed updates subatomic to working pcb 2019-10-30 13:54:46 -04:00
9e64d5f6c2 add encoder matrix functionality 2019-10-30 13:39:18 -04:00
7 changed files with 324 additions and 224 deletions

View File

@ -58,3 +58,11 @@ or `keymap.c`:
## Hardware ## Hardware
The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground. The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground.
## Encoder matrix
You can also wire the C/common line through a diode (arrow towards the row) to each of the rows (or reading pin) in your matrix, and use as many encoders as you have rows (multiplied by the number of A/B lines you have hooked up). To do this, you can add this line to your `config.h` with all of the pins you use:
```c
#define ENCODERS_PAD_C { encoder1c, encoder2c }
```

View File

@ -1,16 +1,14 @@
/* /*
Copyright 2012 Jun Wako <wakojun@gmail.com> Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -24,24 +22,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VENDOR_ID 0xFEED #define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6063 #define PRODUCT_ID 0x6063
#define DEVICE_VER 0x0001 #define DEVICE_VER 0x0001
#define MANUFACTURER Ortholinear Keyboards #define MANUFACTURER OLKB
#define PRODUCT The Subatomic Keyboard #define PRODUCT Subatomic
#define DESCRIPTION A compact ortholinear keyboard #define DESCRIPTION A compact ortholinear keyboard
/* key matrix size */ /* key matrix size */
#define MATRIX_ROWS 5 #define MATRIX_ROWS 10
#define MATRIX_COLS 14 #define MATRIX_COLS 8
/* Planck PCB default pin-out */ /* Planck PCB default pin-out */
#define MATRIX_ROW_PINS { D2, D5, B5, B6, D3 } #define MATRIX_ROW_PINS { A10, A9, A8, B15, C13, C14, C15, A2, A3, A6 }
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7, C6, C5 } #define MATRIX_COL_PINS { B11, B10, B2, B1, A7, B0, B9, B8 }
#define UNUSED_PINS #define UNUSED_PINS
#define ENCODERS_PAD_A { B12 }
#define ENCODERS_PAD_B { B13 }
#define ENCODERS_PAD_C { C13, C14, C15, A2, A3, A6, A10, A9, A8, B15 }
// #define AUDIO_VOICES // #define AUDIO_VOICES
// #define C6_AUDIO // #define C6_AUDIO
#define BACKLIGHT_PIN B7
/* COL2ROW or ROW2COL */ /* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW #define DIODE_DIRECTION COL2ROW
@ -59,6 +60,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Locking resynchronize hack */ /* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE #define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* /*
* Feature disable options * Feature disable options
* These options are also useful to firmware size reduction. * These options are also useful to firmware size reduction.

View File

@ -1,26 +0,0 @@
#pragma once
// place overrides here
/*
* 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 2

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,21 @@
# MCU name # MCU name
MCU = at90usb1286 MCU = STM32F303
# Bootloader selection
# Teensy halfkay
# Pro Micro caterina
# Atmel DFU atmel-dfu
# LUFA DFU lufa-dfu
# QMK DFU qmk-dfu
# ATmega32A bootloadHID
# ATmega328P USBasp
BOOTLOADER = atmel-dfu
# Build Options # Build Options
# change to "no" to disable the options, or define them in the Makefile in # change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically # the appropriate keymap folder that will get included automatically
# #
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) BACKLIGHT_ENABLE = no
MOUSEKEY_ENABLE = no # Mouse keys(+4700) BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
EXTRAKEY_ENABLE = yes # Audio control and System control(+450) ## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.)
CONSOLE_ENABLE = no # Console for debug(+400) MOUSEKEY_ENABLE = yes # Mouse keys
COMMAND_ENABLE = no # Commands for debug and configuration EXTRAKEY_ENABLE = yes # Audio control and System control
NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work CONSOLE_ENABLE = yes # Console for debug
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality COMMAND_ENABLE = yes # Commands for debug and configuration
MIDI_ENABLE = yes # MIDI controls #SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
AUDIO_ENABLE = yes # Audio output on port C6 NKRO_ENABLE = yes # USB Nkey Rollover
UNICODE_ENABLE = no # Unicode #CUSTOM_MATRIX = yes # Custom matrix file
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = yes
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. RGBLIGHT_ENABLE = no
API_SYSEX_ENABLE = no # SERIAL_LINK_ENABLE = yes
ENCODER_ENABLE = 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

View File

@ -25,11 +25,16 @@
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \ k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
) { \ ) { \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d }, \ { k00, k01, k02, k03, k04, k05, KC_NO, KC_NO }, \
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d }, \ { k10, k11, k12, k13, k14, k15, KC_NO, KC_NO }, \
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d }, \ { k20, k21, k22, k23, k24, k25, KC_NO, KC_NO }, \
{ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d }, \ { k30, k31, k32, k33, k34, k35, KC_NO, KC_NO }, \
{ k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d } \ { k06, k07, k08, k09, k0a, k0b, k0c, k0d }, \
{ k16, k17, k18, k19, k1a, k1b, k1c, k1d }, \
{ k26, k27, k28, k29, k2a, k2b, k2c, k2d }, \
{ k36, k37, k38, k39, k3a, k3b, k3c, k3d }, \
{ k40, k41, k42, k49, k4a, k4b, k4c, k4d }, \
{ k46, k47, k48, k43, k44, k45, KC_NO, KC_NO }, \
} }
@ -53,11 +58,16 @@
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, \
k40, k41, k42, k43, k44, k45, k46, k48, k49, k4a, k4b, k4c, k4d \ k40, k41, k42, k43, k44, k45, k46, k48, k49, k4a, k4b, k4c, k4d \
) { \ ) { \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d }, \ { k00, k01, k02, k03, k04, k05, KC_NO, KC_NO }, \
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d }, \ { k10, k11, k12, k13, k14, k15, KC_NO, KC_NO }, \
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d }, \ { k20, k21, k22, k23, k24, k25, KC_NO, KC_NO }, \
{ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d }, \ { k30, k31, k32, k33, k34, k35, KC_NO, KC_NO }, \
{ k40, k41, k42, k43, k44, k45, k46, XXX, k48, k49, k4a, k4b, k4c, k4d } \ { k06, k07, k08, k09, k0a, k0b, k0c, k0d }, \
{ k16, k17, k18, k19, k1a, k1b, k1c, k1d }, \
{ k26, k27, k28, k29, k2a, k2b, k2c, k2d }, \
{ k36, k37, k38, k39, k3a, k3b, k3c, k3d }, \
{ k40, k41, k42, k49, k4a, k4b, k4c, k4d }, \
{ k46, KC_NO, k48, k43, k44, k45, KC_NO, KC_NO }, \
} }
@ -81,9 +91,14 @@
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, \
k40, k41, k42, k43, k44, k45, k47, k49, k4a, k4b, k4c, k4d \ k40, k41, k42, k43, k44, k45, k47, k49, k4a, k4b, k4c, k4d \
) { \ ) { \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d }, \ { k00, k01, k02, k03, k04, k05, KC_NO, KC_NO }, \
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d }, \ { k10, k11, k12, k13, k14, k15, KC_NO, KC_NO }, \
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d }, \ { k20, k21, k22, k23, k24, k25, KC_NO, KC_NO }, \
{ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d }, \ { k30, k31, k32, k33, k34, k35, KC_NO, KC_NO }, \
{ k40, k41, k42, k43, k44, k45, XXX, k47, XXX, k49, k4a, k4b, k4c, k4d } \ { k06, k07, k08, k09, k0a, k0b, k0c, k0d }, \
{ k16, k17, k18, k19, k1a, k1b, k1c, k1d }, \
{ k26, k27, k28, k29, k2a, k2b, k2c, k2d }, \
{ k36, k37, k38, k39, k3a, k3b, k3c, k3d }, \
{ k40, k41, k42, k49, k4a, k4b, k4c, k4d }, \
{ KC_NO, k47, KC_NO, k43, k44, k45, KC_NO, KC_NO }, \
} }

View File

@ -31,10 +31,19 @@
# error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" # error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B"
#endif #endif
#define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
static pin_t encoders_pad_a[] = ENCODERS_PAD_A; static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
static pin_t encoders_pad_b[] = ENCODERS_PAD_B; static pin_t encoders_pad_b[] = ENCODERS_PAD_B;
#ifdef ENCODERS_PAD_C
#define NUMBER_OF_ENCODERS_AB (sizeof(encoders_pad_a) / sizeof(pin_t))
#define NUMBER_OF_ENCODERS_C (sizeof(encoders_pad_c) / sizeof(pin_t))
#define NUMBER_OF_ENCODERS (NUMBER_OF_ENCODERS_C * NUMBER_OF_ENCODERS_AB)
static pin_t encoders_pad_c[] = ENCODERS_PAD_C;
#else
#define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
#define NUMBER_OF_ENCODERS_AB (sizeof(encoders_pad_a) / sizeof(pin_t))
#endif
static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
@ -57,19 +66,51 @@ void encoder_init(void) {
if (!isLeftHand) { if (!isLeftHand) {
const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT;
const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT;
for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { for (uint8_t i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
encoders_pad_a[i] = encoders_pad_a_right[i]; encoders_pad_a[i] = encoders_pad_a_right[i];
encoders_pad_b[i] = encoders_pad_b_right[i]; encoders_pad_b[i] = encoders_pad_b_right[i];
} }
} }
#endif #endif
for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { #ifdef ENCODERS_PAD_C
setPinInputHigh(encoders_pad_a[i]); for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
setPinInputHigh(encoders_pad_b[i]); setPinOutput(encoders_pad_c[i]);
if (i != 0)
writePinHigh(encoders_pad_c[i]);
else
writePinLow(encoders_pad_c[i]);
}
encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); for (int j = 0; j < NUMBER_OF_ENCODERS_C; j++) {
} writePinLow(encoders_pad_c[j]);
wait_us(10);
for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
setPinInputHigh(encoders_pad_a[i]);
setPinInputHigh(encoders_pad_b[i]);
encoder_state[j+(i*NUMBER_OF_ENCODERS_C)] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
}
writePinHigh(encoders_pad_c[j]);
}
// need to disable these pins to prevent matrix activation
for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
setPinInput(encoders_pad_a[i]);
setPinInput(encoders_pad_b[i]);
}
for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
setPinInputLow(encoders_pad_c[i]);
}
#else
for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
setPinInputHigh(encoders_pad_a[i]);
setPinInputHigh(encoders_pad_b[i]);
encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
}
#endif
#ifdef SPLIT_KEYBOARD #ifdef SPLIT_KEYBOARD
thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS; thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS;
@ -89,15 +130,55 @@ static void encoder_update(int8_t index, uint8_t state) {
} }
void encoder_read(void) { void encoder_read(void) {
for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { #ifdef ENCODERS_PAD_C
encoder_state[i] <<= 2; // setup row pins to act as C pins for the encoders, prep the first one
encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
#if SPLIT_KEYBOARD setPinOutput(encoders_pad_c[i]);
encoder_update(i + thisHand, encoder_state[i]); if (i != 0)
#else writePinHigh(encoders_pad_c[i]);
encoder_update(i, encoder_state[i]); else
#endif writePinLow(encoders_pad_c[i]);
} }
// pull these back up because we disabled them earlier
for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
setPinInputHigh(encoders_pad_a[i]);
setPinInputHigh(encoders_pad_b[i]);
}
for (int j = 0; j < NUMBER_OF_ENCODERS_C; j++) {
writePinLow(encoders_pad_c[j]);
wait_us(10);
for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
encoder_state[j+(i*NUMBER_OF_ENCODERS_C)] <<= 2;
encoder_state[j+(i*NUMBER_OF_ENCODERS_C)] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
#if SPLIT_KEYBOARD
encoder_update(j+(i*NUMBER_OF_ENCODERS_C) + thisHand, encoder_state[j+(i*NUMBER_OF_ENCODERS_C)]);
#else
encoder_update(j+(i*NUMBER_OF_ENCODERS_C), encoder_state[j+(i*NUMBER_OF_ENCODERS_C)]);
#endif
}
writePinHigh(encoders_pad_c[j]);
}
// need to disable these pins again to prevent matrix activation
for (int i = 0; i < NUMBER_OF_ENCODERS_AB; i++) {
setPinInput(encoders_pad_a[i]);
setPinInput(encoders_pad_b[i]);
}
// revert row pins back to input
for (int i = 0; i < NUMBER_OF_ENCODERS_C; i++) {
setPinInputLow(encoders_pad_c[i]);
}
#else
for (int i = 0; i < NUMBER_OF_ENCODERS; i++) {
encoder_state[i] <<= 2;
encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
#if SPLIT_KEYBOARD
encoder_update(i + thisHand, encoder_state[i]);
#else
encoder_update(i, encoder_state[i]);
#endif
}
#endif
} }
#ifdef SPLIT_KEYBOARD #ifdef SPLIT_KEYBOARD