Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keybard<->Svalboard communication and customizable layer colors. #79

Merged
merged 10 commits into from
Dec 27, 2024
4 changes: 3 additions & 1 deletion keyboards/svalboard/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define FORCE_NKRO
#define EE_HANDS
//#define DEBUG_MATRIX_SCAN_RATE
#define EECONFIG_KB_DATA_SIZE 5
// Data size is 5 + (16 * 3), to include layer colors in HSV struct.
#define EECONFIG_KB_DATA_SIZE 53


#define FLASH_LEN (16 * 1024 * 1024)
Expand Down Expand Up @@ -94,6 +95,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLIGHT_VAL_STEP 10
#define RGBLIGHT_LED_COUNT 2

#define SPLIT_TRANSACTION_IDS_KB KEYBOARD_SYNC_A

#define PERMISSIVE_HOLD
#define ACHORDION_STREAK
34 changes: 2 additions & 32 deletions keyboards/svalboard/keymaps/vial/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,42 +23,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "svalboard.h"

#define LAYER_COLOR(name, color) rgblight_segment_t const (name)[] = RGBLIGHT_LAYER_SEGMENTS({0, 2, color})

LAYER_COLOR(layer0_colors, HSV_GREEN); // NORMAL
LAYER_COLOR(layer1_colors, HSV_ORANGE); // FUNC
LAYER_COLOR(layer2_colors, HSV_AZURE); // NAS
LAYER_COLOR(layer3_colors, HSV_CORAL); // FKEYS
LAYER_COLOR(layer4_colors, HSV_YELLOW); // use for NORMAL hold?
LAYER_COLOR(layer5_colors, HSV_TEAL); // use for FUNC hold?
LAYER_COLOR(layer6_colors, HSV_RED); // use for NAS hold
LAYER_COLOR(layer7_colors, HSV_RED);
LAYER_COLOR(layer8_colors, HSV_PINK);
LAYER_COLOR(layer9_colors, HSV_PURPLE);
LAYER_COLOR(layer10_colors, HSV_CORAL);
LAYER_COLOR(layer11_colors, HSV_SPRINGGREEN);
LAYER_COLOR(layer12_colors, HSV_TEAL);
LAYER_COLOR(layer13_colors, HSV_TURQUOISE);
LAYER_COLOR(layer14_colors, HSV_YELLOW);
LAYER_COLOR(layer15_colors, HSV_MAGENTA); // MBO
#undef LAYER_COLOR

const rgblight_segment_t* const __attribute((weak))sval_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
layer0_colors, layer1_colors, layer2_colors, layer3_colors,
layer4_colors, layer5_colors, layer6_colors, layer7_colors,
layer8_colors, layer9_colors, layer10_colors, layer11_colors,
layer12_colors, layer13_colors, layer14_colors, layer15_colors
);

layer_state_t default_layer_state_set_user(layer_state_t state) {
rgblight_set_layer_state(0, layer_state_cmp(state, 0));
sval_set_active_layer(0, false);
return state;
}

layer_state_t layer_state_set_user(layer_state_t state) {
for (int i = 0; i < RGBLIGHT_LAYERS; ++i) {
rgblight_set_layer_state(i, layer_state_cmp(state, i));
}
sval_set_active_layer(get_highest_layer(state), false);
return state;
}

Expand Down Expand Up @@ -179,7 +150,6 @@ void keyboard_post_init_user(void) {
//debug_matrix=true;
//debug_keyboard=true;
//debug_mouse=true;
rgblight_layers = sval_rgb_layers;

#if __has_include("keymap_all.h")
if (fresh_install) {
Expand Down
1 change: 1 addition & 0 deletions keyboards/svalboard/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ BOARD = GENERIC_RP_RP2040

# we want some pretty lights
RGBLIGHT_ENABLE = yes
RGBLIGHT_SPLIT = yes
RGBLIGHT_DRIVER = ws2812
WS2812_DRIVER = vendor

Expand Down
115 changes: 115 additions & 0 deletions keyboards/svalboard/svalboard.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "svalboard.h"
#include "eeconfig.h"
#include "version.h"
#include "split_common/transactions.h"

saved_values_t global_saved_values;
const int16_t mh_timer_choices[4] = { 300, 500, 800, -1 }; // -1 is infinite.

uint8_t sval_active_layer = 0;
bool fresh_install = false;

void write_eeprom_kb(void) {
Expand All @@ -24,10 +27,33 @@ void read_eeprom_kb(void) {
global_saved_values.mh_timer_index = 1;
modified = true;
}
if (global_saved_values.version < 3) {
global_saved_values.version = 3;
#define HSV(c) (struct layer_hsv) { (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF}
// Colors from chatgpt.
global_saved_values.layer_colors[0] = HSV(0x55FFFF); // Green
global_saved_values.layer_colors[1] = HSV(0x15FFFF); // Orange
global_saved_values.layer_colors[2] = HSV(0x95FFFF); // Azure
global_saved_values.layer_colors[3] = HSV(0x0BB0FF); // Coral
global_saved_values.layer_colors[4] = HSV(0x2BFFFF); // Yellow
global_saved_values.layer_colors[5] = HSV(0x80FF80); // Teal
global_saved_values.layer_colors[6] = HSV(0x00FFFF); // Red
global_saved_values.layer_colors[7] = HSV(0x00FFFF); // Red
global_saved_values.layer_colors[8] = HSV(0xEAFFFF); // Pink
global_saved_values.layer_colors[9] = HSV(0xBFFF80); // Purple
global_saved_values.layer_colors[10] = HSV(0x0BB0FF); // Coral
global_saved_values.layer_colors[11] = HSV(0x6AFFFF); // Spring Green
global_saved_values.layer_colors[12] = HSV(0x80FF80); // Teal
global_saved_values.layer_colors[13] = HSV(0x80FFFF); // Turquoise
global_saved_values.layer_colors[14] = HSV(0x2BFFFF); // Yellow
global_saved_values.layer_colors[15] = HSV(0xD5FFFF); // Magenta
modified = true;
}
// As we add versions, just append here.
if (modified) {
write_eeprom_kb();
}
sval_active_layer = 0;
}

static const char YES[] = "yes";
Expand Down Expand Up @@ -106,6 +132,9 @@ void set_dpi_from_eeprom(void) {
set_right_dpi(global_saved_values.right_dpi_index);
}

void kb_sync_listener(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
// Just a ping-pong, no need to do anything.
}
// Called from via_init, we can check here if we're a fresh
// installation.
void via_init_kb(void) {
Expand All @@ -116,6 +145,92 @@ void keyboard_post_init_kb(void) {
read_eeprom_kb();
set_dpi_from_eeprom();
keyboard_post_init_user();
transaction_register_rpc(KEYBOARD_SYNC_A, kb_sync_listener);
if (is_keyboard_master()) {
sval_set_active_layer(sval_active_layer, false);
}
}

bool is_connected = false;

void housekeeping_task_kb(void) {
if (is_keyboard_master()) {
static uint32_t last_ping = 0;
if (timer_elapsed(last_ping) > 500) {
presence_rpc_t rpcout = {0};
presence_rpc_t rpcin = {0};
if (transaction_rpc_exec(KEYBOARD_SYNC_A, sizeof(presence_rpc_t), &rpcout, sizeof(presence_rpc_t), &rpcin)) {
if (!is_connected) {
is_connected = true;
sval_on_reconnect();
}
} else {
is_connected = false;
}
last_ping = timer_read32();
}
}
}

void raw_hid_receive_kb(uint8_t *data, uint8_t length) {
// raw_hid_receive_kb uses data for both input and output.
// If a command code is unknown, it is simply echoed back.
struct layer_hsv *cols;
uint8_t layer;
if (data[0] != SVAL_VIA_PREFIX) return;
switch (data[1]) {
case sval_id_get_protocol_version:
data[0] = 's';
data[1] = 'v';
data[2] = 'a';
data[3] = 'l';
data[4] = SVAL_PROTO_VERSION & 0xFF;
data[5] = (SVAL_PROTO_VERSION >> 8) & 0xFF;
data[6] = (SVAL_PROTO_VERSION >> 16) & 0xFF;
data[7] = (SVAL_PROTO_VERSION >> 24) & 0xFF;
break;
case sval_id_get_firmware_version:
snprintf((char *) data, length, "%s", QMK_VERSION);
break;
case sval_id_get_layer_hsv:
layer = data[2];
if (layer > 15) layer = 15;
cols = &global_saved_values.layer_colors[layer];
data[0] = cols->hue;
data[1] = cols->sat;
data[2] = cols->val;
break;
case sval_id_set_layer_hsv:
// Parameters start at data[2].
layer = data[2];
if (layer > 15) layer = 15;
cols = &global_saved_values.layer_colors[layer];
if (cols->hue != data[3] || cols->sat != data[4] || cols->val != data[5]) {
cols->hue = data[3];
cols->sat = data[4];
cols->val = data[5];
write_eeprom_kb();
}
sval_set_active_layer(sval_active_layer, false);
break;
}
}

void sval_on_reconnect(void) {
// Reset colors, or it won't communicate the right color.
rgblight_sethsv_noeeprom(0, 0, 0);
sval_set_active_layer(sval_active_layer, true);
}

void sval_set_active_layer(uint32_t layer, bool save) {
if (layer > 15) layer = 15;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes boards won't have 32 layers, check against the number of layers.

sval_active_layer = layer;
struct layer_hsv cols = global_saved_values.layer_colors[layer];
if (save) {
rgblight_sethsv(cols.hue, cols.sat, cols.val);
} else {
rgblight_sethsv_noeeprom(cols.hue, cols.sat, cols.val);
}
}

#ifndef SVALBOARD_REENABLE_BOOTMAGIC_LITE
Expand Down
26 changes: 26 additions & 0 deletions keyboards/svalboard/svalboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern const int16_t mh_timer_choices[4];
extern bool fresh_install;

struct layer_hsv {
uint8_t hue;
uint8_t sat;
uint8_t val;
};

struct saved_values {
uint8_t version; // Currently at 1, We assume all new data will be zeroed.
bool left_scroll :1;
Expand All @@ -30,8 +36,26 @@ struct saved_values {
uint8_t left_dpi_index;
uint8_t right_dpi_index;
uint8_t mh_timer_index;
struct layer_hsv layer_colors[DYNAMIC_KEYMAP_LAYER_COUNT];
};

#define SVAL_PROTO_VERSION 3

#define SVAL_VIA_PREFIX 0xEE

enum sval_command_ids {
sval_id_get_protocol_version = 0x01,
sval_id_get_firmware_version = 0x02,
// Layer HSVs
sval_id_get_layer_hsv = 0x10,
sval_id_set_layer_hsv = 0x11,
};

// Just for ping pong, do we want anything else for it?
typedef struct _presence_rpc_t {
int presence;
} presence_rpc_t;

typedef struct saved_values saved_values_t;

extern saved_values_t global_saved_values;
Expand All @@ -44,3 +68,5 @@ void set_left_dpi(uint8_t index);
void set_right_dpi(uint8_t index);
void write_eeprom_kb(void);
void recalibrate_pointer(void);
void sval_set_active_layer(uint32_t layer, bool save);
void sval_on_reconnect(void);
Loading