Merge remote-tracking branch 'origin/develop' into xap

This commit is contained in:
QMK Bot 2024-02-26 22:16:29 +00:00
commit 0b65d6419b
46 changed files with 1064 additions and 817 deletions

View file

@ -0,0 +1,391 @@
// Copyright 2023 Andrew Kannan
// SPDX-License-Identifier: GPL-2.0-or-later
#include "satisfaction_core.h"
#include "print.h"
#include "debug.h"
#include <ch.h>
#include <hal.h>
#include "timer.h"
#include "raw_hid.h"
#include "dynamic_keymap.h"
#include "eeprom.h"
#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
/* Artificial delay added to get media keys to work in the encoder*/
#define MEDIA_KEY_DELAY 10
volatile uint8_t led_numlock = false;
volatile uint8_t led_capslock = false;
volatile uint8_t led_scrolllock = false;
uint8_t layer;
bool clock_set_mode = false;
uint8_t oled_mode = OLED_DEFAULT;
bool oled_repaint_requested = false;
bool oled_wakeup_requested = false;
uint32_t oled_sleep_timer;
uint8_t encoder_value = 32;
uint8_t encoder_mode = ENC_MODE_VOLUME;
uint8_t enabled_encoder_modes = 0x1F;
RTCDateTime last_timespec;
uint16_t last_minute = 0;
uint8_t time_config_idx = 0;
int8_t hour_config = 0;
int16_t minute_config = 0;
int8_t year_config = 0;
int8_t month_config = 0;
int8_t day_config = 0;
uint8_t previous_encoder_mode = 0;
void board_init(void) {
SYSCFG->CFGR1 |= SYSCFG_CFGR1_I2C1_DMA_RMP;
SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_SPI2_DMA_RMP);
}
void keyboard_post_init_kb(){
/*
This is a workaround to some really weird behavior
Without this code, the OLED will turn on, but not when you initially plug the keyboard in.
You have to manually trigger a user reset to get the OLED to initialize properly
I'm not sure what the root cause is at this time, but this workaround fixes it.
*/
#ifdef OLED_ENABLE
if(!is_oled_on()){
wait_ms(3000);
oled_init(OLED_ROTATION_0);
}
#endif
}
#ifdef VIA_ENABLE
void custom_set_value(uint8_t *data) {
uint8_t *value_id = &(data[0]);
uint8_t *value_data = &(data[1]);
switch ( *value_id ) {
case id_oled_default_mode:
{
eeprom_update_byte((uint8_t*)EEPROM_DEFAULT_OLED, value_data[0]);
break;
}
case id_oled_mode:
{
oled_mode = value_data[0];
oled_request_wakeup();
break;
}
case id_encoder_modes:
{
uint8_t index = value_data[0];
uint8_t enable = value_data[1];
enabled_encoder_modes = (enabled_encoder_modes & ~(1<<index)) | (enable<<index);
eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, enabled_encoder_modes);
break;
}
case id_encoder_custom:
{
uint8_t custom_encoder_idx = value_data[0];
uint8_t encoder_behavior = value_data[1];
uint16_t keycode = (value_data[2] << 8) | value_data[3];
set_custom_encoder_config(custom_encoder_idx, encoder_behavior, keycode);
break;
}
}
}
void custom_get_value(uint8_t *data) {
uint8_t *value_id = &(data[0]);
uint8_t *value_data = &(data[1]);
switch ( *value_id ) {
case id_oled_default_mode:
{
uint8_t default_oled = eeprom_read_byte((uint8_t*)EEPROM_DEFAULT_OLED);
value_data[0] = default_oled;
break;
}
case id_oled_mode:
{
value_data[0] = oled_mode;
break;
}
case id_encoder_modes:
{
uint8_t index = value_data[0];
value_data[1] = (enabled_encoder_modes & (1<<index)) ? 1 : 0;
break;
}
case id_encoder_custom:
{
uint8_t custom_encoder_idx = value_data[0];
uint8_t encoder_behavior = value_data[1];
uint16_t keycode = retrieve_custom_encoder_config(custom_encoder_idx, encoder_behavior);
value_data[2] = keycode >> 8;
value_data[3] = keycode & 0xFF;
break;
}
}
}
void via_custom_value_command_kb(uint8_t *data, uint8_t length) {
uint8_t *command_id = &(data[0]);
uint8_t *channel_id = &(data[1]);
uint8_t *value_id_and_data = &(data[2]);
if ( *channel_id == id_custom_channel ) {
switch ( *command_id )
{
case id_custom_set_value:
{
custom_set_value(value_id_and_data);
break;
}
case id_custom_get_value:
{
custom_get_value(value_id_and_data);
break;
}
case id_custom_save:
{
// values are saved in custom_set_value()
break;
}
default:
{
// Unhandled message.
*command_id = id_unhandled;
break;
}
}
return;
}
*command_id = id_unhandled;
// DO NOT call raw_hid_send(data,length) here, let caller do this
}
#endif
void read_host_led_state(void) {
led_t led_state = host_keyboard_led_state();
if (led_state.num_lock) {
if (led_numlock == false){
led_numlock = true;}
} else {
if (led_numlock == true){
led_numlock = false;}
}
if (led_state.caps_lock) {
if (led_capslock == false){
led_capslock = true;}
} else {
if (led_capslock == true){
led_capslock = false;}
}
if (led_state.scroll_lock) {
if (led_scrolllock == false){
led_scrolllock = true;}
} else {
if (led_scrolllock == true){
led_scrolllock = false;}
}
}
layer_state_t layer_state_set_kb(layer_state_t state) {
state = layer_state_set_user(state);
layer = get_highest_layer(state);
oled_request_wakeup();
return state;
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
oled_request_wakeup();
switch (keycode) {
case OLED_TOGG:
if(!clock_set_mode){
if (record->event.pressed) {
oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
}
}
return false;
case CLOCK_SET:
if (record->event.pressed) {
if(clock_set_mode){
pre_encoder_mode_change();
clock_set_mode = false;
encoder_mode = previous_encoder_mode;
post_encoder_mode_change();
}else{
previous_encoder_mode = encoder_mode;
pre_encoder_mode_change();
clock_set_mode = true;
encoder_mode = ENC_MODE_CLOCK_SET;
post_encoder_mode_change();
}
}
return false;
case ENC_PRESS:
if (record->event.pressed) {
uint16_t mapped_code = handle_encoder_press();
uint16_t held_keycode_timer = timer_read();
if(mapped_code != 0){
register_code16(mapped_code);
while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
unregister_code16(mapped_code);
}
} else {
// Do something else when release
}
return false;
default:
break;
}
return process_record_user(keycode, record);
}
bool encoder_update_kb(uint8_t index, bool clockwise) {
if (!encoder_update_user(index, clockwise)) return false;
oled_request_wakeup();
encoder_value = (encoder_value + (clockwise ? 1 : -1)) % 64;
if (index == 0) {
if (layer == 0){
uint16_t mapped_code = 0;
if (clockwise) {
mapped_code = handle_encoder_clockwise();
} else {
mapped_code = handle_encoder_ccw();
}
uint16_t held_keycode_timer = timer_read();
if(mapped_code != 0){
register_code16(mapped_code);
while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
unregister_code16(mapped_code);
}
} else {
if(clockwise){
change_encoder_mode(false);
} else {
change_encoder_mode(true);
}
}
}
return true;
}
void custom_config_reset(void){
void *p = (void*)(VIA_EEPROM_CUSTOM_CONFIG_ADDR);
void *end = (void*)(VIA_EEPROM_CUSTOM_CONFIG_ADDR+VIA_EEPROM_CUSTOM_CONFIG_SIZE);
while ( p != end ) {
eeprom_update_byte(p, 0);
++p;
}
eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, 0x1F);
}
void custom_config_load(void){
#ifdef DYNAMIC_KEYMAP_ENABLE
oled_mode = eeprom_read_byte((uint8_t*)EEPROM_DEFAULT_OLED);
enabled_encoder_modes = eeprom_read_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES);
#endif
}
// Called from via_init() if VIA_ENABLE
// Called from matrix_init_kb() if not VIA_ENABLE
void via_init_kb(void)
{
// This checks both an EEPROM reset (from bootmagic lite, keycodes)
// and also firmware build date (from via_eeprom_is_valid())
if (eeconfig_is_enabled()) {
custom_config_load();
} else {
#ifdef DYNAMIC_KEYMAP_ENABLE
// Reset the custom stuff
custom_config_reset();
#endif
// DO NOT set EEPROM valid here, let caller do this
}
}
void matrix_init_kb(void)
{
#ifndef VIA_ENABLE
via_init_kb();
via_eeprom_set_valid(true);
#endif // VIA_ENABLE
rtcGetTime(&RTCD1, &last_timespec);
matrix_init_user();
oled_request_wakeup();
}
void housekeeping_task_kb(void) {
rtcGetTime(&RTCD1, &last_timespec);
uint16_t minutes_since_midnight = last_timespec.millisecond / 1000 / 60;
if (minutes_since_midnight != last_minute){
last_minute = minutes_since_midnight;
oled_request_repaint();
}
}
//
// In the case of VIA being disabled, we still need to check if
// keyboard level EEPROM memory is valid before loading.
// Thus these are copies of the same functions in VIA, since
// the backlight settings reuse VIA's EEPROM magic/version,
// and the ones in via.c won't be compiled in.
//
// Yes, this is sub-optimal, and is only here for completeness
// (i.e. catering to the 1% of people that want wilba.tech LED bling
// AND want persistent settings BUT DON'T want to use dynamic keymaps/VIA).
//
#ifndef VIA_ENABLE
bool via_eeprom_is_valid(void)
{
char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
return (eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0 ) == magic0 &&
eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1 ) == magic1 &&
eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2 ) == magic2 );
}
// Sets VIA/keyboard level usage of EEPROM to valid/invalid
// Keyboard level code (eg. via_init_kb()) should not call this
void via_eeprom_set_valid(bool valid)
{
char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0, valid ? magic0 : 0xFF);
eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1, valid ? magic1 : 0xFF);
eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2, valid ? magic2 : 0xFF);
}
void via_eeprom_reset(void)
{
// Set the VIA specific EEPROM state as invalid.
via_eeprom_set_valid(false);
// Set the TMK/QMK EEPROM state as invalid.
eeconfig_disable();
}
#endif // VIA_ENABLE

View file

@ -0,0 +1,101 @@
// Copyright 2023 Andrew Kannan
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
#include "via.h" // only for EEPROM address
#include "satisfaction_keycodes.h"
#define EEPROM_ENABLED_ENCODER_MODES (VIA_EEPROM_CUSTOM_CONFIG_ADDR)
#define EEPROM_DEFAULT_OLED (VIA_EEPROM_CUSTOM_CONFIG_ADDR+1)
#define EEPROM_CUSTOM_ENCODER (VIA_EEPROM_CUSTOM_CONFIG_ADDR+2)
enum s75_keyboard_value_id {
id_encoder_modes = 1,
id_oled_default_mode,
id_encoder_custom,
id_oled_mode
};
enum encoder_modes {
ENC_MODE_VOLUME,
ENC_MODE_MEDIA,
ENC_MODE_SCROLL,
ENC_MODE_BRIGHTNESS,
ENC_MODE_BACKLIGHT,
ENC_MODE_CUSTOM0,
ENC_MODE_CUSTOM1,
ENC_MODE_CUSTOM2,
_NUM_ENCODER_MODES,
ENC_MODE_CLOCK_SET // This shouldn't be included in the default modes, so we put it after NUM_ENCODER_MODES
};
enum custom_encoder_behavior {
ENC_CUSTOM_CW = 0,
ENC_CUSTOM_CCW,
ENC_CUSTOM_PRESS
};
enum oled_modes {
OLED_DEFAULT,
OLED_TIME,
OLED_OFF,
_NUM_OLED_MODES
};
// Keyboard Information
extern volatile uint8_t led_numlock;
extern volatile uint8_t led_capslock;
extern volatile uint8_t led_scrolllock;
extern uint8_t layer;
// OLED Behavior
extern uint8_t oled_mode;
extern bool oled_repaint_requested;
extern bool oled_wakeup_requested;
extern uint32_t oled_sleep_timer;
// Encoder Behavior
extern uint8_t encoder_value;
extern uint8_t encoder_mode;
extern uint8_t enabled_encoder_modes;
// RTC
extern RTCDateTime last_timespec;
extern uint16_t last_minute;
// RTC Configuration
extern bool clock_set_mode;
extern uint8_t time_config_idx;
extern int8_t hour_config;
extern int16_t minute_config;
extern int8_t year_config;
extern int8_t month_config;
extern int8_t day_config;
extern uint8_t previous_encoder_mode;
// Backlighting
#ifdef BACKLIGHT_ENABLE
extern backlight_config_t kb_backlight_config;
extern bool kb_backlight_breathing;
#endif
void pre_encoder_mode_change(void);
void post_encoder_mode_change(void);
void change_encoder_mode(bool negative);
uint16_t handle_encoder_clockwise(void);
uint16_t handle_encoder_ccw(void);
uint16_t handle_encoder_press(void);
uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior);
void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code);
void update_time_config(int8_t increment);
void oled_request_wakeup(void);
void oled_request_repaint(void);
bool oled_task_needs_to_repaint(void);
void custom_config_load(void);

View file

@ -0,0 +1,231 @@
// Copyright 2023 Andrew Kannan
// SPDX-License-Identifier: GPL-2.0-or-later
#include "satisfaction_core.h"
#include "eeprom.h"
void pre_encoder_mode_change(void){
if(encoder_mode == ENC_MODE_CLOCK_SET){
RTCDateTime timespec;
timespec.year = year_config;
timespec.month = month_config;
timespec.day = day_config;
// timespec.dayofweek = last_timespec.dayofweek;
// timespec.dstflag = last_timespec.dstflag;
timespec.millisecond = (hour_config * 60 + minute_config) * 60 * 1000;
rtcSetTime(&RTCD1, &timespec);
}
}
void post_encoder_mode_change(void){
if(encoder_mode == ENC_MODE_CLOCK_SET){
hour_config = (last_minute / 60);
minute_config = last_minute % 60;
year_config = last_timespec.year;
month_config = last_timespec.month;
day_config = last_timespec.day;
time_config_idx = 0;
}
}
void change_encoder_mode(bool negative){
pre_encoder_mode_change();
if(enabled_encoder_modes == 0){
enabled_encoder_modes = 0x1F;
}
do {
if(negative){
if (encoder_mode == 0){
encoder_mode = _NUM_ENCODER_MODES - 1;
} else{
encoder_mode = encoder_mode - 1;
}
} else {
encoder_mode = (encoder_mode + 1) % _NUM_ENCODER_MODES;
}
} while(((1 << encoder_mode) & enabled_encoder_modes) == 0);
post_encoder_mode_change();
}
void update_time_config(int8_t increment){
uint8_t day_limit = 31;
uint16_t adjusted_year = 1980 + year_config;
switch(time_config_idx){
case 0: // hour
default:
hour_config = (hour_config + increment) % 24;
if (hour_config < 0){
hour_config += 24;
}
break;
case 1: // minute
minute_config = (minute_config + increment) % 60;
if (minute_config < 0){
minute_config += 60;
}
break;
case 2: // year
year_config += increment;
break;
case 3: // month
month_config = (month_config % 12) + increment;
if (month_config <= 0){
month_config += 12;
}
break;
case 4: //day
if (month_config == 9 || month_config == 4 || month_config == 6 || month_config == 11){
day_limit = 30;
} else if(month_config == 2){
day_limit = adjusted_year % 4 == 0 && !(adjusted_year % 100 == 0 && adjusted_year % 400 != 0) ? 29 : 28;
}
day_config = (day_config % day_limit) + increment;
if(day_config <= 0){
day_config += day_limit;
}
break;
}
}
uint16_t handle_encoder_clockwise(void){
uint16_t mapped_code = 0;
switch(encoder_mode){
default:
case ENC_MODE_VOLUME:
mapped_code = KC_VOLU;
break;
case ENC_MODE_MEDIA:
mapped_code = KC_MEDIA_NEXT_TRACK;
break;
case ENC_MODE_SCROLL:
mapped_code = KC_WH_D;
break;
#ifdef BACKLIGHT_ENABLE
case ENC_MODE_BACKLIGHT:
backlight_increase();
if(get_backlight_level() != 0){
backlight_enable();
}
break;
#endif
case ENC_MODE_BRIGHTNESS:
mapped_code = KC_BRIGHTNESS_UP;
break;
#ifdef DYNAMIC_KEYMAP_ENABLE
case ENC_MODE_CUSTOM0:
mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_CW);
break;
case ENC_MODE_CUSTOM1:
mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_CW);
break;
case ENC_MODE_CUSTOM2:
mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_CW);
break;
#endif
case ENC_MODE_CLOCK_SET:
update_time_config(1);
break;
}
return mapped_code;
}
uint16_t handle_encoder_ccw(void){
uint16_t mapped_code = 0;
switch(encoder_mode){
default:
case ENC_MODE_VOLUME:
mapped_code = KC_VOLD;
break;
case ENC_MODE_MEDIA:
mapped_code = KC_MEDIA_PREV_TRACK;
break;
case ENC_MODE_SCROLL:
mapped_code = KC_WH_U;
break;
#ifdef BACKLIGHT_ENABLE
case ENC_MODE_BACKLIGHT:
backlight_decrease();
if(get_backlight_level() == 0){
backlight_disable();
}
break;
#endif
case ENC_MODE_BRIGHTNESS:
mapped_code = KC_BRIGHTNESS_DOWN;
break;
#ifdef DYNAMIC_KEYMAP_ENABLE
case ENC_MODE_CUSTOM0:
mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_CCW);
break;
case ENC_MODE_CUSTOM1:
mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_CCW);
break;
case ENC_MODE_CUSTOM2:
mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_CCW);
break;
#endif
case ENC_MODE_CLOCK_SET:
update_time_config(-1);
break;
}
return mapped_code;
}
uint16_t handle_encoder_press(void){
uint16_t mapped_code = 0;
switch(encoder_mode){
case ENC_MODE_VOLUME:
mapped_code = KC_MUTE;
break;
default:
case ENC_MODE_MEDIA:
mapped_code = KC_MEDIA_PLAY_PAUSE;
break;
case ENC_MODE_SCROLL:
mapped_code = KC_BTN3;
break;
#ifdef BACKLIGHT_ENABLE
case ENC_MODE_BACKLIGHT:
breathing_toggle();
break;
#endif
#ifdef DYNAMIC_KEYMAP_ENABLE
case ENC_MODE_CUSTOM0:
mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_PRESS);
break;
case ENC_MODE_CUSTOM1:
mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_PRESS);
break;
case ENC_MODE_CUSTOM2:
mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_PRESS);
break;
#endif
case ENC_MODE_CLOCK_SET:
time_config_idx = (time_config_idx + 1) % 5;
case ENC_MODE_BRIGHTNESS:
break;
}
return mapped_code;
}
uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){
#ifdef DYNAMIC_KEYMAP_ENABLE
void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2));
//big endian
uint16_t keycode = eeprom_read_byte(addr) << 8;
keycode |= eeprom_read_byte(addr + 1);
return keycode;
#else
return 0;
#endif
}
void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code){
#ifdef DYNAMIC_KEYMAP_ENABLE
void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2));
eeprom_update_byte(addr, (uint8_t)(new_code >> 8));
eeprom_update_byte(addr + 1, (uint8_t)(new_code & 0xFF));
#endif
}

View file

@ -0,0 +1,10 @@
// Copyright 2023 Andrew Kannan
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
enum my_keycodes {
ENC_PRESS = QK_KB_0,
CLOCK_SET,
OLED_TOGG
};

View file

@ -0,0 +1,279 @@
// Copyright 2023 Andrew Kannan
// SPDX-License-Identifier: GPL-2.0-or-later
#include "satisfaction_core.h"
#include <stdio.h>
void draw_default(void);
void draw_clock(void);
#ifdef OLED_ENABLE
oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return OLED_ROTATION_0; }
bool oled_task_kb(void) {
if (!oled_task_user()) { return false; }
if (!oled_task_needs_to_repaint()) {
return false;
}
oled_clear();
if (clock_set_mode) {
draw_clock();
return false;
}
switch (oled_mode) {
default:
case OLED_DEFAULT:
draw_default();
break;
case OLED_TIME:
draw_clock();
break;
}
return false;
}
// Request a repaint of the OLED image without resetting the OLED sleep timer.
// Used for things like clock updates that should not keep the OLED turned on
// if there is no other activity.
void oled_request_repaint(void) {
if (is_oled_on()) {
oled_repaint_requested = true;
}
}
// Request a repaint of the OLED image and reset the OLED sleep timer.
// Needs to be called after any activity that should keep the OLED turned on.
void oled_request_wakeup(void) {
oled_wakeup_requested = true;
}
// Check whether oled_task_user() needs to repaint the OLED image. This
// function should be called at the start of oled_task_user(); it also handles
// the OLED sleep timer and the OLED_OFF mode.
bool oled_task_needs_to_repaint(void) {
// In the OLED_OFF mode the OLED is kept turned off; any wakeup requests
// are ignored.
if ((oled_mode == OLED_OFF) && !clock_set_mode) {
oled_wakeup_requested = false;
oled_repaint_requested = false;
oled_off();
return false;
}
// If OLED wakeup was requested, reset the sleep timer and do a repaint.
if (oled_wakeup_requested) {
oled_wakeup_requested = false;
oled_repaint_requested = false;
oled_sleep_timer = timer_read32() + CUSTOM_OLED_TIMEOUT;
oled_on();
return true;
}
// If OLED repaint was requested, just do a repaint without touching the
// sleep timer.
if (oled_repaint_requested) {
oled_repaint_requested = false;
return true;
}
// If the OLED is currently off, skip the repaint (which would turn the
// OLED on if the image is changed in any way).
if (!is_oled_on()) {
return false;
}
// If the sleep timer has expired while the OLED was on, turn the OLED off.
if (timer_expired32(timer_read32(), oled_sleep_timer)) {
oled_off();
return false;
}
// Always perform a repaint if the OLED is currently on. (This can
// potentially be optimized to avoid unneeded repaints if all possible
// state changes are covered by oled_request_repaint() or
// oled_request_wakeup(), but then any missed calls to these functions
// would result in displaying a stale image.)
return true;
}
static void draw_line_h(uint8_t x, uint8_t y, uint8_t len) {
for (uint8_t i = 0; i < len; i++) {
oled_write_pixel(i + x, y, true);
}
}
static void draw_line_v(uint8_t x, uint8_t y, uint8_t len) {
for (uint8_t i = 0; i < len; i++) {
oled_write_pixel(x, i + y, true);
}
}
static char* get_enc_mode(void) {
switch (encoder_mode) {
default:
case ENC_MODE_VOLUME:
return "VOL";
case ENC_MODE_MEDIA:
return "MED";
case ENC_MODE_SCROLL:
return "SCR";
case ENC_MODE_BRIGHTNESS:
return "BRT";
case ENC_MODE_BACKLIGHT:
return "BKL";
case ENC_MODE_CLOCK_SET:
return "CLK";
case ENC_MODE_CUSTOM0:
return "CS0";
case ENC_MODE_CUSTOM1:
return "CS1";
case ENC_MODE_CUSTOM2:
return "CS2";
}
}
static char* get_time(void) {
uint8_t hour = last_minute / 60;
uint16_t minute = last_minute % 60;
if (encoder_mode == ENC_MODE_CLOCK_SET) {
hour = hour_config;
minute = minute_config;
}
bool is_pm = (hour / 12) > 0;
hour = hour % 12;
if (hour == 0) {
hour = 12;
}
static char time_str[8] = "";
snprintf(time_str, sizeof(time_str), "%02hhu:%02hu%s", hour, minute, is_pm ? "pm" : "am");
return time_str;
}
static char* get_date(void) {
int16_t year = last_timespec.year + 1980;
int8_t month = last_timespec.month;
int8_t day = last_timespec.day;
if (encoder_mode == ENC_MODE_CLOCK_SET) {
year = year_config + 1980;
month = month_config;
day = day_config;
}
static char date_str[11] = "";
snprintf(date_str, sizeof(date_str), "%04hd-%02hhd-%02hhd", year, month, day);
return date_str;
}
void draw_default(void) {
oled_write_P(PSTR("LAYER "), false);
oled_write_char(get_highest_layer(layer_state) + 0x30, true);
oled_write_P(PSTR(" ENC "), false);
oled_write(get_enc_mode(), true);
led_t led_state = host_keyboard_led_state();
oled_set_cursor(18, 0);
oled_write_P(PSTR("CAP"), led_state.caps_lock);
oled_set_cursor(18, 1);
oled_write_P(PSTR("SCR"), led_state.scroll_lock);
uint8_t mod_state = get_mods();
oled_set_cursor(6, 3);
oled_write_P(PSTR("S"), mod_state & MOD_MASK_SHIFT);
oled_advance_char();
oled_write_P(PSTR("C"), mod_state & MOD_MASK_CTRL);
oled_advance_char();
oled_write_P(PSTR("A"), mod_state & MOD_MASK_ALT);
oled_advance_char();
oled_write_P(PSTR("G"), mod_state & MOD_MASK_GUI);
oled_advance_char();
oled_write(get_time(), false);
/* Matrix display is 12 x 12 pixels */
#define MATRIX_DISPLAY_X 0
#define MATRIX_DISPLAY_Y 18
// matrix
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
for (uint8_t y = 0; y < MATRIX_COLS; y++) {
bool on = (matrix_get_row(x) & (1 << y)) > 0;
oled_write_pixel(MATRIX_DISPLAY_X + y + 2, MATRIX_DISPLAY_Y + x + 2, on);
}
}
// outline
draw_line_h(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y, 19);
draw_line_h(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y + 9, 19);
draw_line_v(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y, 9);
draw_line_v(MATRIX_DISPLAY_X + 19, MATRIX_DISPLAY_Y, 9);
// oled location
draw_line_h(MATRIX_DISPLAY_X + 14, MATRIX_DISPLAY_Y + 2, 3);
// bodge extra lines for invert layer and enc mode
draw_line_v(35, 0, 8);
draw_line_v(71, 0, 8);
}
void draw_clock(void) {
oled_set_cursor(0, 0);
oled_write(get_date(), false);
oled_set_cursor(0, 2);
oled_write(get_time(), false);
oled_set_cursor(12, 0);
oled_write_P(PSTR(" ENC "), false);
oled_write(get_enc_mode(), true);
oled_set_cursor(13, 1);
oled_write_P(PSTR("LAYER "), false);
oled_write_char(get_highest_layer(layer_state) + 0x30, true);
led_t led_state = host_keyboard_led_state();
oled_set_cursor(15, 3);
oled_write_P(PSTR("CAPS"), led_state.caps_lock);
if (clock_set_mode) {
switch (time_config_idx) {
case 0: // hour
default:
draw_line_h(0, 25, 10);
break;
case 1: // minute
draw_line_h(18, 25, 10);
break;
case 2: // year
draw_line_h(0, 9, 24);
break;
case 3: // month
draw_line_h(30, 9, 10);
break;
case 4: // day
draw_line_h(48, 9, 10);
break;
}
}
// bodge extra lines for invert layer and enc mode
draw_line_v(101, 0, 8);
draw_line_v(113, 8, 8);
}
#else
void oled_request_repaint(void){
}
void oled_request_wakeup(void){
}
#endif

View file

@ -1,18 +1,5 @@
/* Copyright 2020 QMK
*
* 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/>.
*/
// Copyright 2023 Andrew Kannan (@awkannan)
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* This file was auto-generated by:

View file

@ -1,19 +1,5 @@
/*
Copyright 2015 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/>.
*/
// Copyright 2023 Andrew Kannan (@awkannan)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@ -23,6 +9,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* LSE clock */
#define STM32_LSECLK 32768
#define BACKLIGHT_PWM_DRIVER PWMD3
#define BACKLIGHT_PWM_CHANNEL 1
#define BACKLIGHT_PAL_MODE 1
// I2C config
#define I2C_DRIVER I2CD1
#define I2C1_SCL_PIN B6
@ -53,23 +43,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// dynamic keymaps start after this.
// Custom config Usage:
// 1 for enabled encoder modes (1 byte)
// 1 for custom backlighting controls (1 byte)
// 1 for OLED default mode (1 byte)
// 6 for 3x custom encoder settings, left, right, and press (18 bytes)
#define VIA_EEPROM_CUSTOM_CONFIG_SIZE 21
#define VIA_EEPROM_CUSTOM_CONFIG_SIZE 20
/*
* 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

View file

@ -1,18 +1,5 @@
/* Copyright 2020 QMK
*
* 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/>.
*/
// Copyright 2023 Andrew Kannan (@awkannan)
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* This file was auto-generated by:

View file

@ -1,27 +1,28 @@
{
"keyboard_name": "Satisfaction75",
"manufacturer": "CannonKeys",
"url": "",
"maintainer": "Cannon Keys",
"usb": {
"vid": "0xCA04",
"pid": "0x57F5",
"device_version": "0.0.1"
},
"matrix_pins": {
"cols": ["B1", "B2", "B10", "B11", "B12", "B13", "B14", "A8", "A9", "A10", "B0", "A7", "A5", "B5", "A15", "A1"],
"rows": ["B3", "B4", "A0", "A2", "A4", "A3"]
},
"diode_direction": "COL2ROW",
"encoder": {
"rotary": [
{"pin_a": "B9", "pin_b": "B8", "resolution": 2}
]
},
"keyboard_name": "Satisfaction75",
"maintainer": "awkannan",
"backlight": {
"breathing": true,
"breathing_period": 6,
"levels": 24,
"breathing": true
"pin": "A6"
},
"bootloader": "stm32-dfu",
"features": {
"backlight": true,
"bootmagic": true,
"command": false,
"console": false,
"encoder": true,
"extrakey": true,
"mousekey": true,
"nkro": true,
"oled": true
},
"processor": "STM32F072",
"bootloader": "stm32-dfu"
}
"url": "https://cannonkeys.com",
"usb": {
"vid": "0xCA04"
}
}

View file

@ -1,19 +1,5 @@
/*
Copyright 2012,2013 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/>.
*/
// Copyright 2023 Andrew Kannan (@awkannan)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H

View file

@ -1 +0,0 @@
QWIIC_ENABLE = no

View file

@ -1,19 +1,5 @@
/*
Copyright 2012,2013 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/>.
*/
// Copyright 2023 Andrew Kannan (@awkannan)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H

View file

@ -1,256 +0,0 @@
/*
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/>.
*/
#include <hal.h>
#include "led_custom.h"
#include "satisfaction75.h"
#define BREATHING_PERIOD 6
static void breathing_callback(PWMDriver *pwmp);
static PWMConfig pwmCFG = {
0xFFFF, /* PWM clock frequency */
256, /* PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */
NULL, /* No Callback */
{
{PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* Enable Channel 0 */
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL}
},
0, /* HW dependent part.*/
0
};
static PWMConfig pwmCFG_breathing = {
0xFFFF, /* 10kHz PWM clock frequency */
256, /* PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */
breathing_callback, /* Breathing Callback */
{
{PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* Enable Channel 0 */
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL}
},
0, /* HW dependent part.*/
0
};
// See http://jared.geek.nz/2013/feb/linear-led-pwm
static uint16_t cie_lightness(uint16_t v) {
if (v <= 5243) // if below 8% of max
return v / 9; // same as dividing by 900%
else {
uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
// to get a useful result with integer division, we shift left in the expression above
// and revert what we've done again after squaring.
y = y * y * y >> 8;
if (y > 0xFFFFUL) // prevent overflow
return 0xFFFFU;
else
return (uint16_t) y;
}
}
void backlight_init_ports(void) {
palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(1));
pwmStart(&PWMD3, &pwmCFG);
if(kb_backlight_config.enable){
if(kb_backlight_config.breathing){
breathing_enable();
} else{
backlight_set(kb_backlight_config.level);
}
} else {
backlight_set(0);
}
}
void suspend_power_down_user(void) {
backlight_set(0);
}
void suspend_wakeup_init_user(void) {
if(kb_backlight_config.enable){
if(kb_backlight_config.breathing){
breathing_enable();
} else{
backlight_set(kb_backlight_config.level);
}
} else {
backlight_set(0);
}
}
void backlight_set(uint8_t level) {
uint32_t duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t) level / BACKLIGHT_LEVELS));
if (level == 0) {
// Turn backlight off
pwmDisableChannel(&PWMD3, 0);
} else {
// Turn backlight on
if(!is_breathing()){
pwmEnableChannel(&PWMD3, 0, PWM_FRACTION_TO_WIDTH(&PWMD3,0xFFFF,duty));
}
}
}
uint8_t backlight_tick = 0;
void backlight_task(void) {
}
#define BREATHING_NO_HALT 0
#define BREATHING_HALT_OFF 1
#define BREATHING_HALT_ON 2
#define BREATHING_STEPS 128
static uint8_t breathing_period = BREATHING_PERIOD;
static uint8_t breathing_halt = BREATHING_NO_HALT;
static uint16_t breathing_counter = 0;
bool is_breathing(void) {
return PWMD3.config == &pwmCFG_breathing;
}
#define breathing_min() do {breathing_counter = 0;} while (0)
#define breathing_max() do {breathing_counter = breathing_period * 256 / 2;} while (0)
void breathing_interrupt_enable(void){
pwmStop(&PWMD3);
pwmStart(&PWMD3, &pwmCFG_breathing);
chSysLockFromISR();
pwmEnablePeriodicNotification(&PWMD3);
pwmEnableChannelI(
&PWMD3,
0,
PWM_FRACTION_TO_WIDTH(
&PWMD3,
0xFFFF,
0xFFFF
)
);
chSysUnlockFromISR();
}
void breathing_interrupt_disable(void){
pwmStop(&PWMD3);
pwmStart(&PWMD3, &pwmCFG);
}
void breathing_enable(void)
{
breathing_counter = 0;
breathing_halt = BREATHING_NO_HALT;
breathing_interrupt_enable();
}
void breathing_pulse(void)
{
if (kb_backlight_config.level == 0)
breathing_min();
else
breathing_max();
breathing_halt = BREATHING_HALT_ON;
breathing_interrupt_enable();
}
void breathing_disable(void)
{
breathing_interrupt_disable();
// Restore backlight level
backlight_set(kb_backlight_config.level);
}
void breathing_self_disable(void)
{
if (kb_backlight_config.level == 0)
breathing_halt = BREATHING_HALT_OFF;
else
breathing_halt = BREATHING_HALT_ON;
}
void breathing_toggle(void) {
if (is_breathing()){
breathing_disable();
} else {
breathing_enable();
}
}
void breathing_period_set(uint8_t value)
{
if (!value)
value = 1;
breathing_period = value;
}
void breathing_period_default(void) {
breathing_period_set(BREATHING_PERIOD);
}
void breathing_period_inc(void)
{
breathing_period_set(breathing_period+1);
}
void breathing_period_dec(void)
{
breathing_period_set(breathing_period-1);
}
/* To generate breathing curve in python:
* from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
*/
static const uint8_t breathing_table[BREATHING_STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// Use this before the cie_lightness function.
static inline uint16_t scale_backlight(uint16_t v) {
return v / BACKLIGHT_LEVELS * kb_backlight_config.level;
}
static void breathing_callback(PWMDriver *pwmp)
{
(void)pwmp;
uint16_t interval = (uint16_t) breathing_period * 256 / BREATHING_STEPS;
// resetting after one period to prevent ugly reset at overflow.
breathing_counter = (breathing_counter + 1) % (breathing_period * 256);
uint8_t index = breathing_counter / interval % BREATHING_STEPS;
if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
{
breathing_interrupt_disable();
}
uint32_t duty = cie_lightness(scale_backlight(breathing_table[index] * 256));
chSysLockFromISR();
pwmEnableChannelI(
&PWMD3,
0,
PWM_FRACTION_TO_WIDTH(
&PWMD3,
0xFFFF,
duty
)
);
chSysUnlockFromISR();
}

View file

@ -1,7 +0,0 @@
#pragma once
void backlight_task(void);
void breathing_interrupt_disable(void);
void breathing_interrupt_enable(void);
void breathing_enable(void);
void breathing_disable(void);

View file

@ -1,18 +1,5 @@
/* Copyright 2020 QMK
*
* 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/>.
*/
// Copyright 2023 Andrew Kannan (@awkannan)
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* This file was auto-generated by:

View file

@ -1,24 +1,34 @@
{
"diode_direction": "COL2ROW",
"encoder": {
"rotary": [
{"pin_a": "B9", "pin_b": "B8", "resolution": 2}
]
},
"matrix_pins": {
"cols": ["B1", "B2", "B10", "B11", "B12", "B13", "B14", "A8", "A9", "A10", "B0", "A7", "A5", "B5", "A15", "A1"],
"rows": ["B3", "B4", "A0", "A2", "A4", "A3"]
},
"usb": {
"device_version": "0.0.1",
"pid": "0x57F5"
},
"layouts": {
"LAYOUT_all": {
"layout": [
{"label": "K000", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "K002", "matrix": [0, 2], "x": 1.5, "y": 0},
{"label": "K003", "matrix": [0, 3], "x": 2.5, "y": 0},
{"label": "K004", "matrix": [0, 4], "x": 3.5, "y": 0},
{"label": "K005", "matrix": [0, 5], "x": 4.5, "y": 0},
{"label": "K006", "matrix": [0, 6], "x": 5.75, "y": 0},
{"label": "K007", "matrix": [0, 7], "x": 6.75, "y": 0},
{"label": "K008", "matrix": [0, 8], "x": 7.75, "y": 0},
{"label": "K009", "matrix": [0, 9], "x": 8.75, "y": 0},
{"label": "K010", "matrix": [0, 10], "x": 10, "y": 0},
{"label": "K011", "matrix": [0, 11], "x": 11, "y": 0},
{"label": "K012", "matrix": [0, 12], "x": 12, "y": 0},
{"label": "K013", "matrix": [0, 13], "x": 13, "y": 0},
{"label": "K100", "matrix": [1, 0], "x": 0, "y": 1.25},
{"label": "K101", "matrix": [1, 1], "x": 1, "y": 1.25},
{"label": "K102", "matrix": [1, 2], "x": 2, "y": 1.25},
@ -34,9 +44,7 @@
{"label": "K112", "matrix": [1, 12], "x": 12, "y": 1.25},
{"label": "K113", "matrix": [1, 13], "x": 13, "y": 1.25},
{"label": "K114", "matrix": [1, 14], "x": 14, "y": 1.25},
{"label": "K115", "matrix": [1, 15], "x": 15.5, "y": 1},
{"label": "K200", "matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"label": "K201", "matrix": [2, 1], "x": 1.5, "y": 2.25},
{"label": "K202", "matrix": [2, 2], "x": 2.5, "y": 2.25},
@ -51,9 +59,7 @@
{"label": "K211", "matrix": [2, 11], "x": 11.5, "y": 2.25},
{"label": "K212", "matrix": [2, 12], "x": 12.5, "y": 2.25},
{"label": "K213", "matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"label": "K215", "matrix": [2, 15], "x": 15.5, "y": 2.25},
{"label": "K300", "matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"label": "K301", "matrix": [3, 1], "x": 1.75, "y": 3.25},
{"label": "K302", "matrix": [3, 2], "x": 2.75, "y": 3.25},
@ -68,9 +74,7 @@
{"label": "K311", "matrix": [3, 11], "x": 11.75, "y": 3.25},
{"label": "K312", "matrix": [3, 12], "x": 12.75, "y": 3.25},
{"label": "K313", "matrix": [3, 13], "x": 13.75, "y": 3.25, "w": 1.25},
{"label": "K315", "matrix": [3, 15], "x": 15.5, "y": 3.25},
{"label": "K400", "matrix": [4, 0], "x": 0, "y": 4.25, "w": 1.25},
{"label": "K401", "matrix": [4, 1], "x": 1.25, "y": 4.25},
{"label": "K402", "matrix": [4, 2], "x": 2.25, "y": 4.25},
@ -84,11 +88,8 @@
{"label": "K410", "matrix": [4, 10], "x": 10.25, "y": 4.25},
{"label": "K411", "matrix": [4, 11], "x": 11.25, "y": 4.25},
{"label": "K412", "matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"label": "K413", "matrix": [4, 13], "x": 14.25, "y": 4.5},
{"label": "K415", "matrix": [4, 15], "x": 15.5, "y": 4.25},
{"label": "K500", "matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"label": "K501", "matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"label": "K502", "matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
@ -98,7 +99,6 @@
{"label": "K509", "matrix": [5, 9], "x": 10, "y": 5.25},
{"label": "K510", "matrix": [5, 10], "x": 11, "y": 5.25},
{"label": "K511", "matrix": [5, 11], "x": 12, "y": 5.25},
{"label": "K512", "matrix": [5, 12], "x": 13.25, "y": 5.5},
{"label": "K513", "matrix": [5, 13], "x": 14.25, "y": 5.5},
{"label": "K515", "matrix": [5, 15], "x": 15.25, "y": 5.5}
@ -107,22 +107,18 @@
"LAYOUT_default": {
"layout": [
{"label": "K000", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "K002", "matrix": [0, 2], "x": 1.5, "y": 0},
{"label": "K003", "matrix": [0, 3], "x": 2.5, "y": 0},
{"label": "K004", "matrix": [0, 4], "x": 3.5, "y": 0},
{"label": "K005", "matrix": [0, 5], "x": 4.5, "y": 0},
{"label": "K006", "matrix": [0, 6], "x": 5.75, "y": 0},
{"label": "K007", "matrix": [0, 7], "x": 6.75, "y": 0},
{"label": "K008", "matrix": [0, 8], "x": 7.75, "y": 0},
{"label": "K009", "matrix": [0, 9], "x": 8.75, "y": 0},
{"label": "K010", "matrix": [0, 10], "x": 10, "y": 0},
{"label": "K011", "matrix": [0, 11], "x": 11, "y": 0},
{"label": "K012", "matrix": [0, 12], "x": 12, "y": 0},
{"label": "K013", "matrix": [0, 13], "x": 13, "y": 0},
{"label": "K100", "matrix": [1, 0], "x": 0, "y": 1.25},
{"label": "K101", "matrix": [1, 1], "x": 1, "y": 1.25},
{"label": "K102", "matrix": [1, 2], "x": 2, "y": 1.25},
@ -137,9 +133,7 @@
{"label": "K111", "matrix": [1, 11], "x": 11, "y": 1.25},
{"label": "K112", "matrix": [1, 12], "x": 12, "y": 1.25},
{"label": "K113", "matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"label": "K115", "matrix": [1, 15], "x": 15.5, "y": 1},
{"label": "K200", "matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"label": "K201", "matrix": [2, 1], "x": 1.5, "y": 2.25},
{"label": "K202", "matrix": [2, 2], "x": 2.5, "y": 2.25},
@ -154,9 +148,7 @@
{"label": "K211", "matrix": [2, 11], "x": 11.5, "y": 2.25},
{"label": "K212", "matrix": [2, 12], "x": 12.5, "y": 2.25},
{"label": "K213", "matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"label": "K215", "matrix": [2, 15], "x": 15.5, "y": 2.25},
{"label": "K300", "matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"label": "K301", "matrix": [3, 1], "x": 1.75, "y": 3.25},
{"label": "K302", "matrix": [3, 2], "x": 2.75, "y": 3.25},
@ -170,9 +162,7 @@
{"label": "K310", "matrix": [3, 10], "x": 10.75, "y": 3.25},
{"label": "K311", "matrix": [3, 11], "x": 11.75, "y": 3.25},
{"label": "K312", "matrix": [3, 12], "x": 12.75, "y": 3.25, "w": 2.25},
{"label": "K315", "matrix": [3, 15], "x": 15.5, "y": 3.25},
{"label": "K400", "matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"label": "K401", "matrix": [4, 1], "x": 2.25, "y": 4.25},
{"label": "K402", "matrix": [4, 2], "x": 3.25, "y": 4.25},
@ -185,11 +175,8 @@
{"label": "K409", "matrix": [4, 9], "x": 10.25, "y": 4.25},
{"label": "K410", "matrix": [4, 10], "x": 11.25, "y": 4.25},
{"label": "K411", "matrix": [4, 11], "x": 12.25, "y": 4.25, "w": 1.75},
{"label": "K413", "matrix": [4, 13], "x": 14.25, "y": 4.5},
{"label": "K415", "matrix": [4, 15], "x": 15.5, "y": 4.25},
{"label": "K500", "matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"label": "K501", "matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"label": "K502", "matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
@ -197,11 +184,10 @@
{"label": "K509", "matrix": [5, 9], "x": 10, "y": 5.25},
{"label": "K510", "matrix": [5, 10], "x": 11, "y": 5.25},
{"label": "K511", "matrix": [5, 11], "x": 12, "y": 5.25},
{"label": "K512", "matrix": [5, 12], "x": 13.25, "y": 5.5},
{"label": "K513", "matrix": [5, 13], "x": 14.25, "y": 5.5},
{"label": "K515", "matrix": [5, 15], "x": 15.25, "y": 5.5}
]
}
}
}
}

View file

@ -0,0 +1 @@
# This file intentionally left blank

View file

@ -2,11 +2,39 @@
Satisfaction75 Keyboard
Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan1)
Hardware Supported: STM32F072CBT6
* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
* Hardware Supported: STM32F072CBT6
## Revisions
Please be advised that there are many revisions of Satisfaction75 PCBs.
- Prototype revisions do not really exist in the wild, unless you are one of very few people who have an early pre-production Satisfaction75
- Rev1 was the PCB sold with Round 1 and Round 2 of the Satisfaction75 keyboard group buy, as well as any extra PCBs sold before 2023.
- Rev2 is the PCB sold with the late 2023/early 2024 Injection molded Satisfaction75, and any extra PCBs sold after that. These PCBs also have extra edge cuts to support the injection molded Satisfaction75. It was redesigned from scratch and has a little less layout support compared to Rev1.
Revision 2 PCBs will have Revision 2 printed on the PCBs.
Revisions _are_ backwards compatible, so you can use a Rev2 PCB in a board that originally had a Rev1 PCB in it. They are _not_ forwards compatible - Rev 1 PCBs will not work in the injection molded Satisfaction75.
Change the below commands to reflect the revision you need!
## Building and Flashing
Make example for this keyboard (after setting up your build environment):
make cannonkeys/Satisfaction75:default
make cannonkeys/satisfaction75/rev1:default
Flashing example for this keyboard:
make cannonkeys/satisfaction75/rev1:default:flash
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).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
* **Physical reset button**: Toggle the switch on the back of the pcb to "1" and briefly press the button on the back of the PCB
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

View file

@ -1,24 +1,34 @@
{
"diode_direction": "COL2ROW",
"encoder": {
"rotary": [
{"pin_a": "B9", "pin_b": "B8", "resolution": 2}
]
},
"matrix_pins": {
"cols": ["B1", "B2", "B10", "B11", "B12", "B13", "B14", "A8", "A9", "A10", "B0", "A7", "A5", "B5", "A15", "A1"],
"rows": ["B3", "B4", "A0", "A2", "A4", "A3"]
},
"usb": {
"device_version": "0.0.1",
"pid": "0x57F5"
},
"layouts": {
"LAYOUT_default": {
"LAYOUT_2x2": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
@ -32,10 +42,9 @@
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 13], "x": 13, "y": 1.25},
{"matrix": [1, 14], "x": 14, "y": 1.25},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
@ -50,9 +59,7 @@
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
@ -66,9 +73,7 @@
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
@ -81,119 +86,13 @@
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 5], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
},
"LAYOUT_iso": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 12], "x": 12.75, "y": 3.25},
{"matrix": [3, 13], "x": 13.75, "y": 2.25, "w": 1.25, "h": 2},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 1.25},
{"matrix": [4, 1], "x": 1.25, "y": 4.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 5], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.5},
{"matrix": [5, 1], "x": 1.5, "y": 5.25, "w": 1.5},
{"matrix": [5, 5], "x": 3, "y": 5.25, "w": 7},
{"matrix": [5, 9], "x": 10, "y": 5.25, "w": 1.5},
{"matrix": [5, 11], "x": 11.5, "y": 5.25, "w": 1.5},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
@ -202,22 +101,18 @@
"LAYOUT_3x2": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
@ -232,9 +127,7 @@
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
@ -249,9 +142,7 @@
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
@ -265,9 +156,7 @@
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
@ -280,217 +169,14 @@
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 5], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 9], "x": 10, "y": 5.25, "w": 1.5},
{"matrix": [5, 11], "x": 11.5, "y": 5.25, "w": 1.5},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
},
"LAYOUT_2x2": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25},
{"matrix": [1, 14], "x": 14, "y": 1.25},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.5},
{"matrix": [5, 1], "x": 1.5, "y": 5.25, "w": 1.5},
{"matrix": [5, 5], "x": 3, "y": 5.25, "w": 7},
{"matrix": [5, 9], "x": 10, "y": 5.25, "w": 1.5},
{"matrix": [5, 11], "x": 11.5, "y": 5.25, "w": 1.5},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
},
"LAYOUT_split_space": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 3], "x": 3.75, "y": 5.25, "w": 2.25},
{"matrix": [5, 5], "x": 6, "y": 5.25, "w": 1.25},
{"matrix": [5, 7], "x": 7.25, "y": 5.25, "w": 2.75},
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
@ -499,22 +185,18 @@
"LAYOUT_all": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
@ -530,9 +212,7 @@
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25},
{"matrix": [1, 14], "x": 14, "y": 1.25},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
@ -547,9 +227,7 @@
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
@ -564,9 +242,7 @@
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 12], "x": 12.75, "y": 3.25},
{"matrix": [3, 13], "x": 13.75, "y": 3.25, "w": 1.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 1.25},
{"matrix": [4, 1], "x": 1.25, "y": 4.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
@ -580,11 +256,8 @@
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
@ -594,11 +267,268 @@
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
},
"LAYOUT_default": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 5], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
},
"LAYOUT_iso": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 12], "x": 12.75, "y": 3.25},
{"matrix": [3, 13], "x": 13.75, "y": 2.25, "w": 1.25, "h": 2},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 1.25},
{"matrix": [4, 1], "x": 1.25, "y": 4.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 5], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
},
"LAYOUT_split_space": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 2], "x": 1.5, "y": 0},
{"matrix": [0, 3], "x": 2.5, "y": 0},
{"matrix": [0, 4], "x": 3.5, "y": 0},
{"matrix": [0, 5], "x": 4.5, "y": 0},
{"matrix": [0, 6], "x": 5.75, "y": 0},
{"matrix": [0, 7], "x": 6.75, "y": 0},
{"matrix": [0, 8], "x": 7.75, "y": 0},
{"matrix": [0, 9], "x": 8.75, "y": 0},
{"matrix": [0, 10], "x": 10, "y": 0},
{"matrix": [0, 11], "x": 11, "y": 0},
{"matrix": [0, 12], "x": 12, "y": 0},
{"matrix": [0, 13], "x": 13, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
{"matrix": [1, 15], "x": 15.5, "y": 1},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [2, 15], "x": 15.5, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.5, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 13], "x": 14.25, "y": 4.5},
{"matrix": [4, 15], "x": 15.5, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 3], "x": 3.75, "y": 5.25, "w": 2.25},
{"matrix": [5, 5], "x": 6, "y": 5.25, "w": 1.25},
{"matrix": [5, 7], "x": 7.25, "y": 5.25, "w": 2.75},
{"matrix": [5, 9], "x": 10, "y": 5.25},
{"matrix": [5, 10], "x": 11, "y": 5.25},
{"matrix": [5, 11], "x": 12, "y": 5.25},
{"matrix": [5, 12], "x": 13.25, "y": 5.5},
{"matrix": [5, 13], "x": 14.25, "y": 5.5},
{"matrix": [5, 15], "x": 15.25, "y": 5.5}
]
}
}
}
}

View file

@ -0,0 +1,3 @@
#pragma once
#define ENCODER_RESOLUTION 2

Some files were not shown because too many files have changed in this diff Show more