Last active
January 10, 2023 20:05
-
-
Save weskerfoot/6c1f2d13e5f2f9c8d5e555b0cc870b50 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include QMK_KEYBOARD_H | |
#include "print.h" | |
#include <stdint.h> | |
/* The following defines the configuration for the UART driver. */ | |
/*! | |
* UART BAUD rate. This is the speed that we transmit at. For the 1MHz | |
* RC clock, 4800 is the maximum speed (out of the "standard" ones) that | |
* will work. If you're running at 8MHz or with an external crystal, you | |
* may go higher. | |
*/ | |
#define UART_BAUD (9600) | |
#define UART_TX_PORT PORTF /*!< GPIO port register for Tx */ | |
#define UART_TX_DDR DDRF /*!< GPIO direction register for Tx */ | |
#define UART_TX_BIT DDF7 /*!< GPIO pin for Tx */ | |
// Constants for signaling the adafruit chip | |
#define BT_ON 0xff | |
#define BT_OFF 0xfe | |
#define FUNC_ON 0xf2 | |
#define FUNC_OFF 0xf1 | |
static inline void uart_init(void); | |
static inline void uart_tx(uint8_t); | |
static inline void uart_tx_str(const char*); | |
static inline void uart_tx_16(uint16_t); | |
#define TX_BIT (1 << UART_TX_BIT) | |
#define BIT_US (1000000/UART_BAUD) /*!< Bit period in microseconds */ | |
enum custom_keycodes { | |
RGB_MODE = SAFE_RANGE, | |
BRT_UP, | |
BRT_DOWN, | |
SWITCH_RGB_MODE | |
}; | |
static inline void | |
uart_init(void) { | |
UART_TX_DDR |= TX_BIT; | |
UART_TX_PORT |= TX_BIT; | |
} | |
/*! | |
* Send a raw byte to the UART. | |
* It is best to keep this function as short as possible | |
*/ | |
static inline void | |
uart_tx(uint8_t byte) { | |
uint8_t mask = 1; | |
/* Start bit */ | |
// Set the bit for our gpio pin, to the opposite of the current value | |
// it should actually be 0 though, since 1 will mean it's idle | |
UART_TX_PORT &= ~TX_BIT; _delay_us(BIT_US); | |
while(mask) { | |
if (mask & byte) | |
// Set it to 1, TX_BIT is always 1 for that bit | |
UART_TX_PORT |= TX_BIT; | |
else | |
// Set it to 0, ~TX_BIT is always 0 for that bit | |
UART_TX_PORT &= ~TX_BIT; | |
_delay_us(BIT_US); | |
// Shift left by 1 bit (i.e. up another power of two) | |
mask <<= 1; | |
} | |
/* Stop bit */ | |
UART_TX_PORT |= TX_BIT; _delay_us(BIT_US); | |
} | |
/*! | |
* Send a text string (in pgmspace) to the UART. | |
* String shall be null-terminated! | |
*/ | |
static inline void | |
uart_tx_str(const char* str) { | |
char c = pgm_read_byte(str); | |
while (c) { | |
str++; | |
uart_tx(c); | |
c = pgm_read_byte(str); | |
} | |
} | |
static inline void | |
uart_tx_key(uint16_t code, char state) { | |
unsigned char l = code & 0x00ff; | |
unsigned char h = code >> 8; | |
//uprintf("l = %u\n", l); | |
//uprintf("h = %u\n", h); | |
cli(); | |
uart_tx(l); | |
uart_tx(h); | |
uart_tx(state); | |
sei(); | |
} | |
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |
[0] = LAYOUT_all( /* 0: qwerty */ | |
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_GRV, | |
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_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, | |
KC_LSFT, TG(2), 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_LALT, KC_LALT, KC_SPC, TG(1), KC_RGUI, KC_APP, KC_DELETE | |
), | |
[1] = LAYOUT_all( /* 1: fn */ | |
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_UP, _______, RGB_MODE, SWITCH_RGB_MODE, _______, _______, _______, KC_PGDN, KC_PGUP, BRT_DOWN, BRT_UP, _______, | |
_______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |
_______, _______, _______, _______, _______, _______, _______, _______ | |
), | |
[2] = LAYOUT_all( /* 2: arrows */ | |
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | |
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_UP, _______, | |
_______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT | |
), | |
}; | |
void | |
matrix_scan_user(void) { | |
uint32_t layer = layer_state; | |
if (layer & (1<<1)) { | |
} | |
if (layer & (1<<2)) { | |
gh60_poker_leds_on(); | |
gh60_esc_led_on(); | |
} else { | |
gh60_poker_leds_off(); | |
gh60_esc_led_off(); | |
} | |
}; | |
void | |
keyboard_post_init_user(void) { | |
// Customise these values to desired behaviour | |
uart_init(); | |
debug_enable=true; | |
//debug_matrix=true; | |
debug_keyboard=true; | |
cli(); | |
uart_tx(0xff); | |
sei(); | |
} | |
layer_state_t | |
layer_state_set_user(layer_state_t state) { | |
uprintf("code = %u\n", get_highest_layer(state)); | |
switch (get_highest_layer(state)) { | |
case 0: | |
print("function keys inactive"); | |
uart_tx(FUNC_OFF); // normal | |
break; | |
case 1: | |
print("function keys active"); | |
uart_tx(FUNC_ON); // function key active | |
break; | |
} | |
return state; | |
} | |
bool | |
process_record_user(uint16_t keycode, keyrecord_t *record) { | |
static int ctrl_down = 0; | |
static int shift_down = 0; | |
static int caps_down = 0; | |
static int bluetooth_enabled = 0; | |
static int lights_enabled = 0; | |
// TODO, use custom keycodes that only exist in layer state 1 for rgb lighting | |
switch (keycode) { | |
// Always return true for the function keys, so that the other function can process them | |
case TG(1): | |
return true; | |
// For these modifier keys, we want to keep track of them | |
case KC_LCTRL: | |
if (record->event.pressed) { | |
ctrl_down = record->event.pressed; | |
} | |
else { | |
ctrl_down = !ctrl_down; | |
} | |
break; | |
case KC_LSHIFT: | |
if (record->event.pressed) { | |
shift_down = record->event.pressed; | |
} | |
else { | |
shift_down = !shift_down; | |
} | |
break; | |
// Caps lock is a special snowflake so we toggle it instead | |
case KC_CAPS: | |
if (record->event.pressed) { | |
caps_down = !caps_down; | |
} | |
break; | |
// Controls bluetooth | |
case KC_B: | |
if (record->event.pressed) { | |
if (ctrl_down && shift_down) { | |
bluetooth_enabled = !bluetooth_enabled; | |
if (bluetooth_enabled) { | |
uart_tx(BT_ON); | |
} | |
else { | |
uart_tx(BT_OFF); | |
} | |
// Ignore no matter wbat state it's in | |
// release all keys here | |
clear_keyboard(); | |
return false; | |
} | |
} | |
default: | |
break; | |
} | |
if (keycode == SWITCH_RGB_MODE) { | |
} | |
// Send certain keys even if bt is disabled or not. | |
if (keycode == KC_CAPS || | |
keycode == KC_LSHIFT || | |
keycode == KC_LCTRL || | |
keycode == RGB_MODE || | |
keycode == SWITCH_RGB_MODE || | |
keycode == BRT_UP || | |
keycode == BRT_DOWN) { | |
if (record->event.pressed) { | |
uprintf("keycode down = %u\n", keycode); | |
uart_tx_key(keycode, 1); | |
} | |
else { | |
uart_tx_key(keycode, 0); | |
} | |
return !bluetooth_enabled; | |
} | |
else if (bluetooth_enabled || lights_enabled) { | |
if (record->event.pressed) { | |
uart_tx_key(keycode, 1); | |
} | |
else { | |
uart_tx_key(keycode, 0); | |
} | |
return false; | |
} | |
else { | |
// send them anyway but don't return false (meaning it will actually get registered) | |
if (record->event.pressed) { | |
uart_tx_key(keycode, 1); | |
} | |
else { | |
uart_tx_key(keycode, 0); | |
} | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment