This commit is contained in:
Vincent Franco 2025-07-23 13:39:25 -07:00 committed by GitHub
commit 6a90551211
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 2204 additions and 0 deletions

View File

@ -0,0 +1,13 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_3x5(
KC_Q , KC_W , KC_F , KC_P , KC_B , KC_J , KC_L , KC_U , KC_Y , KC_SCLN ,
KC_A , KC_R , KC_S , KC_T , KC_G , KC_M , KC_N , KC_E , KC_I , KC_O ,
KC_Z , KC_X , KC_C , KC_D , KC_V , KC_K , KC_H , KC_COMM , KC_DOT , KC_SLSH ,
XXXXXXX , KC_ESC , KC_SPC , KC_ENT, KC_BSPC , KC_DEL
)
};

View File

@ -0,0 +1,269 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
/*
* Keycodes, combos, and layers! oh my!
*/
enum CROSSES_LAYERS {
_BASE,
_NUM,
_NAV,
_MEDIA,
_FUNC,
_MOUS,
};
enum my_keycodes {
VIMS = SAFE_RANGE,
LARR,
FARR,
EPIP,
LVBC,
RVBC,
BARR,
MSE_INC,
MSE_DEC,
DRAG_SCROLL,
MSE_TOGG,
};
enum combos {
WY_TAB,
DH_CAPS,
HCOMA_MINS,
WSPC_VIM,
FU_QUOTE,
PL_DQUOTE,
CCOM_LARR,
XDOT_FARR,
GM_EPIP,
COMD_UNDERS,
ZDOT_BARR,
};
const uint16_t PROGMEM wy_combo[] = {KC_W, KC_Y, COMBO_END};
const uint16_t PROGMEM dh_combo[] = {KC_D, KC_H, COMBO_END};
const uint16_t PROGMEM hcomma_combo[] = {KC_H, KC_COMM, COMBO_END};
const uint16_t PROGMEM wspc_combo[] = {KC_W, KC_SPC, COMBO_END};
const uint16_t PROGMEM fu_combo[] = {KC_F, KC_U, COMBO_END};
const uint16_t PROGMEM pl_combo[] = {KC_P, KC_L, COMBO_END};
const uint16_t PROGMEM ccom_combo[] = {KC_C, KC_COMM, COMBO_END};
const uint16_t PROGMEM xdot_combo[] = {KC_X, KC_DOT, COMBO_END};
const uint16_t PROGMEM gm_combo[] = {KC_G, KC_M, COMBO_END};
const uint16_t PROGMEM comd_combo[] = {KC_COMM, KC_DOT, COMBO_END};
const uint16_t PROGMEM zdot_combo[] = {KC_Z, KC_DOT, COMBO_END};
// clang-format off
//
combo_t key_combos[] = {
[WY_TAB] = COMBO(wy_combo, KC_TAB),
[DH_CAPS] = COMBO(dh_combo, CW_TOGG),
[HCOMA_MINS] = COMBO(hcomma_combo, KC_MINS),
[WSPC_VIM] = COMBO(wspc_combo, VIMS),
[FU_QUOTE] = COMBO(fu_combo, KC_QUOT),
[PL_DQUOTE] = COMBO(pl_combo, S(KC_QUOT)),
[CCOM_LARR] = COMBO(ccom_combo, LARR),
[XDOT_FARR] = COMBO(xdot_combo, FARR),
[GM_EPIP] = COMBO(gm_combo, EPIP),
[COMD_UNDERS] = COMBO(comd_combo, S(KC_MINS)),
[ZDOT_BARR] = COMBO(zdot_combo, BARR),
};
/*
* Keymaps!
*/
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// ┌───────────┬───────────┬───────────┬───────────┬────────────┐ ┌──────┬────────────┬───────────┬───────────┬───────────┐
// │ q │ w │ f │ p │ b │ │ j │ l │ u │ y │ ; │
// ├───────────┼───────────┼───────────┼───────────┼────────────┤ ├──────┼────────────┼───────────┼───────────┼───────────┤
// │ LGUI_T(a) │ LALT_T(r) │ LCTL_T(s) │ LSFT_T(t) │ g │ │ m │ RSFT_T(n) │ RCTL_T(e) │ RALT_T(i) │ RGUI_T(o) │
// ├───────────┼───────────┼───────────┼───────────┼────────────┤ ├──────┼────────────┼───────────┼───────────┼───────────┤
// │ z │ x │ c │ d │ v │ │ k │ h │ , │ . │ LT(3, /) │
// └───────────┴───────────┴───────────┼───────────┼────────────┼─────┐ ┌────────────┼──────┼────────────┼───────────┴───────────┴───────────┘
// │ MO(5) │ LT(2, esc) │ spc │ │ LT(1, ent) │ bspc │ LT(4, del) │
// └───────────┴────────────┴─────┘ └────────────┴──────┴────────────┘
[_BASE] = LAYOUT_3x5(
KC_Q , KC_W , KC_F , KC_P , KC_B , KC_J , KC_L , KC_U , KC_Y , KC_SCLN ,
LGUI_T(KC_A) , LALT_T(KC_R) , LCTL_T(KC_S) , LSFT_T(KC_T) , KC_G , KC_M , RSFT_T(KC_N) , RCTL_T(KC_E) , RALT_T(KC_I) , RGUI_T(KC_O) ,
KC_Z , KC_X , KC_C , KC_D , KC_V , KC_K , KC_H , KC_COMM , KC_DOT , LT(3, KC_SLSH),
MO(5) , LT(2, KC_ESC) , KC_SPC , LT(1, KC_ENT) , KC_BSPC , LT(4, KC_DEL)
),
// ┌──────┬───┬───┬───────────┬──────┐ ┌──────┬───────────┬───────────┬──────┬─────┐
// │ S(8) │ 7 │ 8 │ 9 │ / │ │ \ │ S(9) │ S(0) │ S(\) │ │
// ├──────┼───┼───┼───────────┼──────┤ ├──────┼───────────┼───────────┼──────┼─────┤
// │ - │ 4 │ 5 │ LSFT_T(6) │ S(=) │ │ S(5) │ RSFT_T([) │ RCTL_T(]) │ S(;) │ ; │
// ├──────┼───┼───┼───────────┼──────┤ ├──────┼───────────┼───────────┼──────┼─────┤
// │ ` │ 1 │ 2 │ 3 │ = │ │ [ │ ] │ │ │ │
// └──────┴───┴───┼───────────┼──────┼─────┐ ┌─────┼──────┼───────────┼───────────┴──────┴─────┘
// │ │ 0 │ │ │ │ │ │
// └───────────┴──────┴─────┘ └─────┴──────┴───────────┘
[_NUM] = LAYOUT_3x5(
S(KC_8) , KC_7 , KC_8 , KC_9 , KC_SLSH , KC_BSLS , S(KC_9) , S(KC_0) , S(KC_BSLS) , KC_TRNS,
KC_MINS , KC_4 , KC_5 , LSFT_T(KC_6) , S(KC_EQL) , S(KC_5) , RSFT_T(KC_LBRC) , RCTL_T(KC_RBRC) , S(KC_SCLN) , KC_SCLN,
KC_GRV , KC_1 , KC_2 , KC_3 , KC_EQL , KC_LBRC , KC_RBRC , KC_TRNS , KC_TRNS , KC_TRNS,
KC_TRNS , KC_0 , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
),
// ┌──────┬──────┬──────┬───────┬────┐ ┌────┬──────┬──────┬──────┬──────┐
// │ no │ no │ no │ no │ no │ │ no │ no │ no │ no │ no │
// ├──────┼──────┼──────┼───────┼────┤ ├────┼──────┼──────┼──────┼──────┤
// │ lgui │ lalt │ lctl │ lsft │ no │ │ no │ left │ down │ up │ rght │
// ├──────┼──────┼──────┼───────┼────┤ ├────┼──────┼──────┼──────┼──────┤
// │ no │ no │ copy │ paste │ no │ │ no │ home │ end │ pgdn │ pgup │
// └──────┴──────┴──────┼───────┼────┼────┐ ┌────┼────┼──────┼──────┴──────┴──────┘
// │ no │ no │ no │ │ no │ no │ no │
// └───────┴────┴────┘ └────┴────┴──────┘
[_NAV] = LAYOUT_3x5(
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
KC_LGUI , KC_LALT , KC_LCTL , KC_LSFT , KC_NO , KC_NO , KC_LEFT , KC_DOWN , KC_UP , KC_RGHT,
KC_NO , KC_NO , KC_COPY , KC_PSTE , KC_NO , KC_NO , KC_HOME , KC_END , KC_PGDN , KC_PGUP,
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO
),
// ┌──────┬──────┬──────┬──────┬──────┐ ┌────┬────┬────┬────┬────┐
// │ no │ no │ no │ no │ no │ │ no │ no │ no │ no │ no │
// ├──────┼──────┼──────┼──────┼──────┤ ├────┼────┼────┼────┼────┤
// │ mprv │ vold │ mply │ volu │ mnxt │ │ no │ no │ no │ no │ no │
// ├──────┼──────┼──────┼──────┼──────┤ ├────┼────┼────┼────┼────┤
// │ no │ no │ no │ no │ no │ │ no │ no │ no │ no │ no │
// └──────┴──────┴──────┼──────┼──────┼────┐ ┌────┼────┼────┼────┴────┴────┘
// │ no │ no │ no │ │ no │ no │ no │
// └──────┴──────┴────┘ └────┴────┴────┘
[_MEDIA] = LAYOUT_3x5(
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO,
KC_MPRV , KC_VOLD , KC_MPLY , KC_VOLU , KC_MNXT , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO,
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO,
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO
),
// ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬──────┬──────┬──────┬──────┐
// │ f11 │ f12 │ f13 │ f14 │ f15 │ │ │ │ │ │ │
// ├─────┼─────┼─────┼─────┼─────┤ ├─────┼──────┼──────┼──────┼──────┤
// │ f6 │ f7 │ f8 │ f9 │ f10 │ │ │ rsft │ rctl │ ralt │ rgui │
// ├─────┼─────┼─────┼─────┼─────┤ ├─────┼──────┼──────┼──────┼──────┤
// │ f1 │ f2 │ f3 │ f4 │ f5 │ │ │ │ │ │ │
// └─────┴─────┴─────┼─────┼─────┼─────┐ ┌─────┼─────┼──────┼──────┴──────┴──────┘
// │ │ │ │ │ │ │ │
// └─────┴─────┴─────┘ └─────┴─────┴──────┘
[_FUNC] = LAYOUT_3x5(
KC_F11 , KC_F12 , KC_F13 , KC_F14 , KC_F15 , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS,
KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_TRNS , KC_RSFT , KC_RCTL , KC_RALT , KC_RGUI,
KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS,
KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
),
// ┌──────┬─────────┬─────────┬─────────────┬────┐ ┌────────┬─────────┬─────────┬──────────┬─────────┐
// │ lsft │ lalt │ no │ no │ no │ │ EE_CLR │ MSE_INC │ MSE_DEC │ no │ no │
// ├──────┼─────────┼─────────┼─────────────┼────┤ ├────────┼─────────┼─────────┼──────────┼─────────┤
// │ lctl │ MS_BTN3 │ MS_BTN2 │ MS_BTN1 │ no │ │ no │ rsft │ rctl │ ralt │ rgui │
// ├──────┼─────────┼─────────┼─────────────┼────┤ ├────────┼─────────┼─────────┼──────────┼─────────┤
// │ lgui │ no │ no │ DRAG_SCROLL │ no │ │ no │ no │ no │ MSE_TOGG │ DB_TOGG │
// └──────┴─────────┴─────────┼─────────────┼────┼────┐ ┌────┼────────┼─────────┼─────────┴──────────┴─────────┘
// │ │ no │ no │ │ no │ no │ no │
// └─────────────┴────┴────┘ └────┴────────┴─────────┘
[_MOUS] = LAYOUT_3x5(
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , EE_CLR , MSE_INC , MSE_DEC , KC_NO , KC_NO ,
KC_NO , MS_BTN3 , MS_BTN2 , MS_BTN1 , KC_NO , KC_NO , KC_RSFT , KC_RCTL , KC_RALT , KC_RGUI,
KC_NO , KC_NO , KC_NO , DRAG_SCROLL , KC_NO , KC_NO , KC_NO , KC_NO , MSE_TOGG , DB_TOGG,
KC_TRNS , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO
)
};
// clang-format on
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
switch (keycode) {
case RSFT_T(KC_LBRC):
if (record->tap.count && record->event.pressed) {
tap_code16(S(KC_LBRC));
return false;
}
break;
case RCTL_T(KC_RBRC):
if (record->tap.count && record->event.pressed) {
tap_code16(S(KC_RBRC));
return false;
}
break;
case VIMS:
if (record->event.pressed) {
tap_code16(KC_ESC);
SEND_STRING(":w\n");
return false;
}
break;
case EPIP:
if (record->event.pressed) {
SEND_STRING("|> ");
return false;
}
break;
case LARR:
if (record->event.pressed) {
SEND_STRING("-> ");
return false;
}
break;
case FARR:
if (record->event.pressed) {
SEND_STRING("=> ");
return false;
}
break;
case BARR:
if (record->event.pressed) {
SEND_STRING("<- ");
return false;
}
break;
case MSE_INC:
if (record->event.pressed) {
#if defined(POINTING_DEVICE_COMBINED) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_LEFT)
change_pointer_dpi(&global_user_config, true);
#endif /* ifdef POINTING_DEVICE */
debug_config_to_console(&global_user_config);
return false;
}
break;
case MSE_DEC:
if (record->event.pressed) {
change_pointer_dpi(&global_user_config, false);
debug_config_to_console(&global_user_config);
return false;
}
break;
case MSE_TOGG:
if (record->event.pressed) {
#if defined(POINTING_DEVICE_COMBINED) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_LEFT)
bool current_state = get_auto_mouse_enable();
set_auto_mouse_enable(!current_state);
#endif /* ifdef POINTING_DEVICE */
return false;
}
break;
case DRAG_SCROLL:
set_scrolling = record->event.pressed;
break;
}
return true;
}

View File

@ -0,0 +1,2 @@
COMBO_ENABLE = yes
CAPS_WORD_ENABLE = yes

View File

@ -0,0 +1,23 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.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/>.
*/
/*
* OLED
*/
#define I2C_DRIVER I2CD1
#define I2C1_SCL_PIN GP15
#define I2C1_SDA_PIN GP14

View File

@ -0,0 +1,53 @@
{
"keyboard_name": "Crosses 3x5 rev1",
"matrix_pins": {
"cols": ["GP26", "GP22", "GP21", "GP23", "GP20"],
"rows": ["GP27", "GP28", "GP29", "GP9"]
},
"usb": {
"device_version": "0.3.0",
"pid": "0x5647"
},
"layouts": {
"LAYOUT_3x5": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0.25},
{"matrix": [0, 1], "x": 1, "y": 0.125},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0.125},
{"matrix": [0, 4], "x": 4, "y": 0.25},
{"matrix": [4, 4], "x": 7, "y": 0.25},
{"matrix": [4, 3], "x": 8, "y": 0.125},
{"matrix": [4, 2], "x": 9, "y": 0},
{"matrix": [4, 1], "x": 10, "y": 0.125},
{"matrix": [4, 0], "x": 11, "y": 0.25},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.125},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [1, 3], "x": 3, "y": 1.125},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [5, 4], "x": 7, "y": 1.25},
{"matrix": [5, 3], "x": 8, "y": 1.125},
{"matrix": [5, 2], "x": 9, "y": 1},
{"matrix": [5, 1], "x": 10, "y": 1.125},
{"matrix": [5, 0], "x": 11, "y": 1.25},
{"matrix": [2, 0], "x": 0, "y": 2.25},
{"matrix": [2, 1], "x": 1, "y": 2.125},
{"matrix": [2, 2], "x": 2, "y": 2},
{"matrix": [2, 3], "x": 3, "y": 2.125},
{"matrix": [2, 4], "x": 4, "y": 2.25},
{"matrix": [6, 4], "x": 7, "y": 2.25},
{"matrix": [6, 3], "x": 8, "y": 2.125},
{"matrix": [6, 2], "x": 9, "y": 2},
{"matrix": [6, 1], "x": 10, "y": 2.125},
{"matrix": [6, 0], "x": 11, "y": 2.25},
{"matrix": [3, 2], "x": 2.5, "y": 3.25},
{"matrix": [3, 3], "x": 3.5, "y": 3.5},
{"matrix": [3, 4], "x": 4.5, "y": 3.75},
{"matrix": [7, 4], "x": 6.5, "y": 3.75},
{"matrix": [7, 3], "x": 7.5, "y": 3.5},
{"matrix": [7, 2], "x": 8.5, "y": 3.25}
]
}
}
}

View File

@ -0,0 +1,22 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 TRUE

View File

@ -0,0 +1 @@
POINTING_DEVICE_DRIVER = pmw3360

View File

@ -0,0 +1,23 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.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/>.
*/
/*
* OLED
*/
#define I2C_DRIVER I2CD0
#define I2C1_SDA_PIN GP8
#define I2C1_SCL_PIN GP9

View File

@ -0,0 +1,53 @@
{
"keyboard_name": "Crosses 36 Rev2",
"matrix_pins": {
"cols": ["GP26", "GP22", "GP21", "GP23", "GP20"],
"rows": ["GP27", "GP28", "GP29", "GP7"]
},
"usb": {
"device_version": "0.3.0",
"pid": "0x5657"
},
"layouts": {
"LAYOUT_3x5": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0.25},
{"matrix": [0, 1], "x": 1, "y": 0.125},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 3, "y": 0.125},
{"matrix": [0, 4], "x": 4, "y": 0.25},
{"matrix": [4, 4], "x": 7, "y": 0.25},
{"matrix": [4, 3], "x": 8, "y": 0.125},
{"matrix": [4, 2], "x": 9, "y": 0},
{"matrix": [4, 1], "x": 10, "y": 0.125},
{"matrix": [4, 0], "x": 11, "y": 0.25},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.125},
{"matrix": [1, 2], "x": 2, "y": 1},
{"matrix": [1, 3], "x": 3, "y": 1.125},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [5, 4], "x": 7, "y": 1.25},
{"matrix": [5, 3], "x": 8, "y": 1.125},
{"matrix": [5, 2], "x": 9, "y": 1},
{"matrix": [5, 1], "x": 10, "y": 1.125},
{"matrix": [5, 0], "x": 11, "y": 1.25},
{"matrix": [2, 0], "x": 0, "y": 2.25},
{"matrix": [2, 1], "x": 1, "y": 2.125},
{"matrix": [2, 2], "x": 2, "y": 2},
{"matrix": [2, 3], "x": 3, "y": 2.125},
{"matrix": [2, 4], "x": 4, "y": 2.25},
{"matrix": [6, 4], "x": 7, "y": 2.25},
{"matrix": [6, 3], "x": 8, "y": 2.125},
{"matrix": [6, 2], "x": 9, "y": 2},
{"matrix": [6, 1], "x": 10, "y": 2.125},
{"matrix": [6, 0], "x": 11, "y": 2.25},
{"matrix": [3, 2], "x": 2.5, "y": 3.25},
{"matrix": [3, 3], "x": 3.5, "y": 3.5},
{"matrix": [3, 4], "x": 4.5, "y": 3.75},
{"matrix": [7, 4], "x": 6.5, "y": 3.75},
{"matrix": [7, 3], "x": 7.5, "y": 3.5},
{"matrix": [7, 2], "x": 8.5, "y": 3.25}
]
}
}
}

View File

@ -0,0 +1,25 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C0
#define RP_I2C_USE_I2C0 TRUE
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 FALSE

View File

@ -0,0 +1 @@
POINTING_DEVICE_DRIVER = pmw3389

View File

@ -0,0 +1,14 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_3x6(
KC_ESC , KC_Q , KC_W , KC_F , KC_P , KC_B , KC_J , KC_L , KC_U , KC_Y , KC_SCLN , KC_BSPC ,
KC_TAB , KC_A , KC_R , KC_S , KC_T , KC_G , KC_M , KC_N , KC_E , KC_I , KC_O , KC_ENTER ,
KC_LSFT , KC_Z , KC_X , KC_C , KC_D , KC_V , KC_K , KC_H , KC_COMM , KC_DOT , KC_SLSH , KC_RSFT ,
XXXXXXX , KC_ESC , KC_SPC , KC_ENT, KC_BSPC , KC_DEL
)
};

View File

@ -0,0 +1,257 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include "action_layer.h"
#include QMK_KEYBOARD_H
/*
* Keycodes, combos, and layers! oh my!
*/
enum CROSSES_LAYERS {
_BASE,
_NUM,
_NAV,
_MEDIA,
_FUNC,
_MOUS,
};
enum my_keycodes {
VIMS = SAFE_RANGE,
LARR,
FARR,
EPIP,
LVBC,
RVBC,
BARR,
MSE_INC,
MSE_DEC,
DRAG_SCROLL,
};
enum combos {
WY_TAB,
DH_CAPS,
HCOMA_MINS,
WSPC_VIM,
FU_QUOTE,
PL_DQUOTE,
CCOM_LARR,
XDOT_FARR,
GM_EPIP,
COMD_UNDERS,
ZDOT_BARR,
};
const uint16_t PROGMEM wy_combo[] = {KC_W, KC_Y, COMBO_END};
const uint16_t PROGMEM dh_combo[] = {KC_D, KC_H, COMBO_END};
const uint16_t PROGMEM hcomma_combo[] = {KC_H, KC_COMM, COMBO_END};
const uint16_t PROGMEM wspc_combo[] = {KC_W, KC_SPC, COMBO_END};
const uint16_t PROGMEM fu_combo[] = {KC_F, KC_U, COMBO_END};
const uint16_t PROGMEM pl_combo[] = {KC_P, KC_L, COMBO_END};
const uint16_t PROGMEM ccom_combo[] = {KC_C, KC_COMM, COMBO_END};
const uint16_t PROGMEM xdot_combo[] = {KC_X, KC_DOT, COMBO_END};
const uint16_t PROGMEM gm_combo[] = {KC_G, KC_M, COMBO_END};
const uint16_t PROGMEM comd_combo[] = {KC_COMM, KC_DOT, COMBO_END};
const uint16_t PROGMEM zdot_combo[] = {KC_Z, KC_DOT, COMBO_END};
// clang-format off
//
combo_t key_combos[] = {
[WY_TAB] = COMBO(wy_combo, KC_TAB),
[DH_CAPS] = COMBO(dh_combo, CW_TOGG),
[HCOMA_MINS] = COMBO(hcomma_combo, KC_MINS),
[WSPC_VIM] = COMBO(wspc_combo, VIMS),
[FU_QUOTE] = COMBO(fu_combo, KC_QUOT),
[PL_DQUOTE] = COMBO(pl_combo, S(KC_QUOT)),
[CCOM_LARR] = COMBO(ccom_combo, LARR),
[XDOT_FARR] = COMBO(xdot_combo, FARR),
[GM_EPIP] = COMBO(gm_combo, EPIP),
[COMD_UNDERS] = COMBO(comd_combo, S(KC_MINS)),
[ZDOT_BARR] = COMBO(zdot_combo, BARR),
};
/*
* Keymaps!
*/
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// ┌───────────┌───────────┬───────────┬───────────┬───────────┬────────────┐ ┌──────┬────────────┬───────────┬───────────┬───────────┬───────────┐
// │ esc │ q │ w │ f │ p │ b │ │ j │ l │ u │ y │ ; │ bkspc │
// ├───────────├───────────┼───────────┼───────────┼───────────┼────────────┤ ├──────┼────────────┼───────────┼───────────┼───────────┼───────────┤
// │ tab │ LGUI_T(a) │ LALT_T(r) │ LCTL_T(s) │ LSFT_T(t) │ g │ │ m │ RSFT_T(n) │ RCTL_T(e) │ RALT_T(i) │ RGUI_T(o) │ enter │
// ├───────────├───────────┼───────────┼───────────┼───────────┼────────────┤ ├──────┼────────────┼───────────┼───────────┼───────────┼───────────┤
// │ shift │ z │ x │ c │ d │ v │ │ k │ h │ , │ . │ LT(3, /) │ shift │
// └───────────└───────────┴───────────┴───────────┼───────────┼────────────┼─────┐ ┌────────────┼──────┼────────────┼───────────┴───────────┴───────────┴───────────┘
// │ MO(5) │ LT(2, esc) │ spc │ │ LT(1, ent) │ bspc │ LT(4, del) │
// └───────────┴────────────┴─────┘ └────────────┴──────┴────────────┘
[_BASE] = LAYOUT_3x6(
KC_ESC ,KC_Q , KC_W , KC_F , KC_P , KC_B , KC_J , KC_L , KC_U , KC_Y , KC_SCLN , KC_BSPC,
KC_TAB ,LGUI_T(KC_A) , LALT_T(KC_R) , LCTL_T(KC_S) , LSFT_T(KC_T) , KC_G , KC_M , RSFT_T(KC_N) , RCTL_T(KC_E) , RALT_T(KC_I) , RGUI_T(KC_O) , KC_ENTER,
KC_LSFT ,KC_Z , KC_X , KC_C , KC_D , KC_V , KC_K , KC_H , KC_COMM , KC_DOT , LT(3, KC_SLSH), KC_RSFT,
MO(5) , LT(2, KC_ESC) , KC_SPC , LT(1, KC_ENT) , KC_BSPC , LT(4, KC_DEL)
),
// ┌──────┬───┬───┬───────────┬──────┐ ┌──────┬───────────┬───────────┬──────┬─────┐
// │ S(8) │ 7 │ 8 │ 9 │ / │ │ \ │ S(9) │ S(0) │ S(\) │ │
// ├──────┼───┼───┼───────────┼──────┤ ├──────┼───────────┼───────────┼──────┼─────┤
// │ - │ 4 │ 5 │ LSFT_T(6) │ S(=) │ │ S(5) │ RSFT_T([) │ RCTL_T(]) │ S(;) │ ; │
// ├──────┼───┼───┼───────────┼──────┤ ├──────┼───────────┼───────────┼──────┼─────┤
// │ ` │ 1 │ 2 │ 3 │ = │ │ [ │ ] │ │ │ │
// └──────┴───┴───┼───────────┼──────┼─────┐ ┌─────┼──────┼───────────┼───────────┴──────┴─────┘
// │ │ 0 │ │ │ │ │ │
// └───────────┴──────┴─────┘ └─────┴──────┴───────────┘
[_NUM] = LAYOUT_3x6(
KC_NO, S(KC_8) , KC_7 , KC_8 , KC_9 , KC_SLSH , KC_BSLS , S(KC_9) , S(KC_0) , S(KC_BSLS) , KC_TRNS, KC_NO,
KC_NO, KC_MINS , KC_4 , KC_5 , LSFT_T(KC_6) , S(KC_EQL) , S(KC_5) , RSFT_T(KC_LBRC) , RCTL_T(KC_RBRC) , S(KC_SCLN) , KC_SCLN, KC_NO,
KC_NO, KC_GRV , KC_1 , KC_2 , KC_3 , KC_EQL , KC_LBRC , KC_RBRC , KC_TRNS , KC_TRNS , KC_TRNS, KC_NO,
KC_TRNS , KC_0 , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
),
// ┌──────┬──────┬──────┬───────┬────┐ ┌────┬──────┬──────┬──────┬──────┐
// │ no │ no │ no │ no │ no │ │ no │ no │ no │ no │ no │
// ├──────┼──────┼──────┼───────┼────┤ ├────┼──────┼──────┼──────┼──────┤
// │ lgui │ lalt │ lctl │ lsft │ no │ │ no │ left │ down │ up │ rght │
// ├──────┼──────┼──────┼───────┼────┤ ├────┼──────┼──────┼──────┼──────┤
// │ no │ no │ copy │ paste │ no │ │ no │ home │ end │ pgdn │ pgup │
// └──────┴──────┴──────┼───────┼────┼────┐ ┌────┼────┼──────┼──────┴──────┴──────┘
// │ no │ no │ no │ │ no │ no │ no │
// └───────┴────┴────┘ └────┴────┴──────┘
[_NAV] = LAYOUT_3x6(
KC_NO, KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO,
KC_NO, KC_LGUI , KC_LALT , KC_LCTL , KC_LSFT , KC_NO , KC_NO , KC_LEFT , KC_DOWN , KC_UP , KC_RGHT, KC_NO,
KC_NO, KC_NO , KC_NO , KC_COPY , KC_PSTE , KC_NO , KC_NO , KC_HOME , KC_END , KC_PGDN , KC_PGUP, KC_NO,
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO
),
// ┌──────┬──────┬──────┬──────┬──────┐ ┌────┬────┬────┬────┬────┐
// │ no │ no │ no │ no │ no │ │ no │ no │ no │ no │ no │
// ├──────┼──────┼──────┼──────┼──────┤ ├────┼────┼────┼────┼────┤
// │ mprv │ vold │ mply │ volu │ mnxt │ │ no │ no │ no │ no │ no │
// ├──────┼──────┼──────┼──────┼──────┤ ├────┼────┼────┼────┼────┤
// │ no │ no │ no │ no │ no │ │ no │ no │ no │ no │ no │
// └──────┴──────┴──────┼──────┼──────┼────┐ ┌────┼────┼────┼────┴────┴────┘
// │ no │ no │ no │ │ no │ no │ no │
// └──────┴──────┴────┘ └────┴────┴────┘
[_MEDIA] = LAYOUT_3x6(
KC_NO, KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO, KC_NO,
KC_NO, KC_MPRV , KC_VOLD , KC_MPLY , KC_VOLU , KC_MNXT , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO, KC_NO,
KC_NO, KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO, KC_NO,
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO
),
// ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬──────┬──────┬──────┬──────┐
// │ f11 │ f12 │ f13 │ f14 │ f15 │ │ │ │ │ │ │
// ├─────┼─────┼─────┼─────┼─────┤ ├─────┼──────┼──────┼──────┼──────┤
// │ f6 │ f7 │ f8 │ f9 │ f10 │ │ │ rsft │ rctl │ ralt │ rgui │
// ├─────┼─────┼─────┼─────┼─────┤ ├─────┼──────┼──────┼──────┼──────┤
// │ f1 │ f2 │ f3 │ f4 │ f5 │ │ │ │ │ │ │
// └─────┴─────┴─────┼─────┼─────┼─────┐ ┌─────┼─────┼──────┼──────┴──────┴──────┘
// │ │ │ │ │ │ │ │
// └─────┴─────┴─────┘ └─────┴─────┴──────┘
[_FUNC] = LAYOUT_3x6(
KC_NO, KC_F11 , KC_F12 , KC_F13 , KC_F14 , KC_F15 , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS, KC_NO,
KC_NO, KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_TRNS , KC_RSFT , KC_RCTL , KC_RALT , KC_RGUI, KC_NO,
KC_NO, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS, KC_NO,
KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
),
// ┌──────┬─────────┬─────────┬─────────────┬────┐ ┌────────┬─────────┬─────────┬──────┬─────────┐
// │ lsft │ lalt │ no │ no │ no │ │ EE_CLR │ MSE_INC │ MSE_DEC │ no │ no │
// ├──────┼─────────┼─────────┼─────────────┼────┤ ├────────┼─────────┼─────────┼──────┼─────────┤
// │ lctl │ MS_BTN3 │ MS_BTN2 │ MS_BTN1 │ no │ │ no │ rsft │ rctl │ ralt │ rgui │
// ├──────┼─────────┼─────────┼─────────────┼────┤ ├────────┼─────────┼─────────┼──────┼─────────┤
// │ lgui │ no │ no │ DRAG_SCROLL │ no │ │ no │ no │ no │ no │ DB_TOGG │
// └──────┴─────────┴─────────┼─────────────┼────┼────┐ ┌────┼────────┼─────────┼─────────┴──────┴─────────┘
// │ │ no │ no │ │ no │ no │ no │
// └─────────────┴────┴────┘ └────┴────────┴─────────┘
[_MOUS] = LAYOUT_3x6(
KC_NO, KC_LSFT , KC_LALT , KC_NO , KC_NO , KC_NO , EE_CLR , MSE_INC , MSE_DEC , KC_NO , KC_NO , KC_NO,
KC_NO, KC_LCTL , MS_BTN3 , MS_BTN2 , MS_BTN1 , KC_NO , KC_NO , KC_RSFT , KC_RCTL , KC_RALT , KC_RGUI, KC_NO,
KC_NO, KC_LGUI , KC_NO , KC_NO , DRAG_SCROLL , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , DB_TOGG, KC_NO,
KC_TRNS , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO
)
};
// clang-format on
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
switch (keycode) {
case RSFT_T(KC_LBRC):
if (record->tap.count && record->event.pressed) {
tap_code16(S(KC_LBRC));
return false;
}
break;
case RCTL_T(KC_RBRC):
if (record->tap.count && record->event.pressed) {
tap_code16(S(KC_RBRC));
return false;
}
break;
case VIMS:
if (record->event.pressed) {
tap_code16(KC_ESC);
SEND_STRING(":w\n");
return false;
}
break;
case EPIP:
if (record->event.pressed) {
SEND_STRING("|> ");
return false;
}
break;
case LARR:
if (record->event.pressed) {
SEND_STRING("-> ");
return false;
}
break;
case FARR:
if (record->event.pressed) {
SEND_STRING("=> ");
return false;
}
break;
case BARR:
if (record->event.pressed) {
SEND_STRING("<- ");
return false;
}
break;
case MSE_INC:
if (record->event.pressed) {
change_pointer_dpi(&global_user_config, true);
debug_config_to_console(&global_user_config);
return false;
}
break;
case MSE_DEC:
if (record->event.pressed) {
change_pointer_dpi(&global_user_config, false);
debug_config_to_console(&global_user_config);
return false;
}
break;
case DRAG_SCROLL:
set_scrolling = record->event.pressed;
break;
}
return true;
}

View File

@ -0,0 +1,2 @@
COMBO_ENABLE = yes
CAPS_WORD_ENABLE = yes

View File

@ -0,0 +1,23 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.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/>.
*/
/*
* OLED
*/
#define I2C_DRIVER I2CD1
#define I2C1_SCL_PIN GP15
#define I2C1_SDA_PIN GP14

View File

@ -0,0 +1,59 @@
{
"keyboard_name": "Crosses 3x6 rev1",
"matrix_pins": {
"cols": ["GP13", "GP26", "GP22", "GP21", "GP23", "GP20"],
"rows": ["GP27", "GP28", "GP29", "GP9"]
},
"usb": {
"device_version": "0.3.0",
"pid": "0x5648"
},
"layouts": {
"LAYOUT_3x6": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 1},
{"matrix": [0, 1], "x": 1, "y": 1},
{"matrix": [0, 2], "x": 2, "y": 0.5},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0.25},
{"matrix": [0, 5], "x": 5, "y": 0.5},
{"matrix": [4, 5], "x": 9, "y": 0.5},
{"matrix": [4, 4], "x": 10, "y": 0.25},
{"matrix": [4, 3], "x": 11, "y": 0},
{"matrix": [4, 2], "x": 12, "y": 0.5},
{"matrix": [4, 1], "x": 13, "y": 1},
{"matrix": [4, 0], "x": 14, "y": 1},
{"matrix": [1, 0], "x": 0, "y": 2},
{"matrix": [1, 1], "x": 1, "y": 2},
{"matrix": [1, 2], "x": 2, "y": 1.5},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.5},
{"matrix": [5, 5], "x": 9, "y": 1.5},
{"matrix": [5, 4], "x": 10, "y": 1.25},
{"matrix": [5, 3], "x": 11, "y": 1},
{"matrix": [5, 2], "x": 12, "y": 1.5},
{"matrix": [5, 1], "x": 13, "y": 2},
{"matrix": [5, 0], "x": 14, "y": 2},
{"matrix": [2, 0], "x": 0, "y": 3},
{"matrix": [2, 1], "x": 1, "y": 3},
{"matrix": [2, 2], "x": 2, "y": 2.5},
{"matrix": [2, 3], "x": 3, "y": 2},
{"matrix": [2, 4], "x": 4, "y": 2.25},
{"matrix": [2, 5], "x": 5, "y": 2.5},
{"matrix": [6, 5], "x": 9, "y": 2.5},
{"matrix": [6, 4], "x": 10, "y": 2.25},
{"matrix": [6, 3], "x": 11, "y": 2},
{"matrix": [6, 2], "x": 12, "y": 2.5},
{"matrix": [6, 1], "x": 13, "y": 3},
{"matrix": [6, 0], "x": 14, "y": 3},
{"matrix": [3, 3], "x": 3, "y": 4},
{"matrix": [3, 4], "x": 4, "y": 4},
{"matrix": [3, 5], "x": 5, "y": 4},
{"matrix": [7, 5], "x": 9, "y": 4},
{"matrix": [7, 4], "x": 10, "y": 4},
{"matrix": [7, 3], "x": 11, "y": 4}
]
}
}
}

View File

@ -0,0 +1,22 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 TRUE

View File

@ -0,0 +1 @@
POINTING_DEVICE_DRIVER = pmw3360

View File

@ -0,0 +1,23 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.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/>.
*/
/*
* OLED
*/
#define I2C_DRIVER I2CD0
#define I2C1_SDA_PIN GP8
#define I2C1_SCL_PIN GP9

View File

@ -0,0 +1,59 @@
{
"keyboard_name": "Crosses 3x6 rev2",
"matrix_pins": {
"cols": ["GP1", "GP26", "GP22", "GP21", "GP23", "GP20"],
"rows": ["GP27", "GP28", "GP29", "GP7"]
},
"usb": {
"device_version": "0.3.0",
"pid": "0x5658"
},
"layouts": {
"LAYOUT_3x6": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 1},
{"matrix": [0, 1], "x": 1, "y": 1},
{"matrix": [0, 2], "x": 2, "y": 0.5},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0.25},
{"matrix": [0, 5], "x": 5, "y": 0.5},
{"matrix": [4, 5], "x": 9, "y": 0.5},
{"matrix": [4, 4], "x": 10, "y": 0.25},
{"matrix": [4, 3], "x": 11, "y": 0},
{"matrix": [4, 2], "x": 12, "y": 0.5},
{"matrix": [4, 1], "x": 13, "y": 1},
{"matrix": [4, 0], "x": 14, "y": 1},
{"matrix": [1, 0], "x": 0, "y": 2},
{"matrix": [1, 1], "x": 1, "y": 2},
{"matrix": [1, 2], "x": 2, "y": 1.5},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.5},
{"matrix": [5, 5], "x": 9, "y": 1.5},
{"matrix": [5, 4], "x": 10, "y": 1.25},
{"matrix": [5, 3], "x": 11, "y": 1},
{"matrix": [5, 2], "x": 12, "y": 1.5},
{"matrix": [5, 1], "x": 13, "y": 2},
{"matrix": [5, 0], "x": 14, "y": 2},
{"matrix": [2, 0], "x": 0, "y": 3},
{"matrix": [2, 1], "x": 1, "y": 3},
{"matrix": [2, 2], "x": 2, "y": 2.5},
{"matrix": [2, 3], "x": 3, "y": 2},
{"matrix": [2, 4], "x": 4, "y": 2.25},
{"matrix": [2, 5], "x": 5, "y": 2.5},
{"matrix": [6, 5], "x": 9, "y": 2.5},
{"matrix": [6, 4], "x": 10, "y": 2.25},
{"matrix": [6, 3], "x": 11, "y": 2},
{"matrix": [6, 2], "x": 12, "y": 2.5},
{"matrix": [6, 1], "x": 13, "y": 3},
{"matrix": [6, 0], "x": 14, "y": 3},
{"matrix": [3, 3], "x": 3, "y": 4},
{"matrix": [3, 4], "x": 4, "y": 4},
{"matrix": [3, 5], "x": 5, "y": 4},
{"matrix": [7, 5], "x": 9, "y": 4},
{"matrix": [7, 4], "x": 10, "y": 4},
{"matrix": [7, 3], "x": 11, "y": 4}
]
}
}
}

View File

@ -0,0 +1,25 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C0
#define RP_I2C_USE_I2C0 TRUE
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 FALSE

View File

@ -0,0 +1 @@
POINTING_DEVICE_DRIVER = pmw3389

View File

@ -0,0 +1,20 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_4x6(
//,-------------------------------------------------------. ,-----------------------------------------------------------.
KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_MINUS ,
//|--------+--------+--------+--------+--------+----------| |---------+--------+--------+-----------+--------+----------|
KC_ESC , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_BSPC ,
//|--------+--------+--------+--------+--------+----------| |---------+--------+--------+-----------+--------+----------|
KC_TAB , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_BSPC, KC_QUOT ,
//|--------+--------+--------+--------+--------+----------| |---------+--------+--------+-----------+--------+----------|
KC_LSFT , KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT ,
//|--------+--------+--------+--------+--------+----------+---------| |-------+---------+--------+--------+-----------+--------+----------|
KC_LGUI , KC_SPC ,XXXXXXX , KC_ENTER, XXXXXXX , KC_RALT
//`-----------------------------' `--------------------------'
)
};

View File

@ -0,0 +1,175 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
/*
* Keycodes, combos, and layers! oh my!
*/
enum CROSSES_LAYERS { _BASE, _NUM, _NAV, _MEDIA, _FUNC, _MOUS, _CUST };
enum crosses_keycode { C_MINC = QK_KB_0, C_MDEC, C_MTOGG, C_DRAG };
#define CTAB LCTL_T(KC_TAB)
#define SCLM LT(_MEDIA, KC_SCLN)
#define C_SMOUS LT(_MOUS, KC_SPC)
#define LNAV MO(_NAV)
#define RENTR LT(_NUM, KC_ENT)
#define LNUM MO(_NUM)
#define RALTD RALT_T(KC_DEL)
/*
* Keymaps!
*/
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_GRV ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 , KC_6 , KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_MINUS ,
//|--------+--------+--------+--------+--------+----------| |------+--------+--------+-----------+--------+----------|
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC ,
//|--------+--------+--------+--------+--------+----------| |------+--------+--------+-----------+--------+----------|
CTAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, SCLM, KC_QUOT ,
//|--------+--------+--------+--------+--------+----------| |------+--------+--------+-----------+--------+----------|
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT ,
//|--------+--------+--------+--------+--------+----------+---------| |-------+------+--------+--------+-----------+--------+----------|
KC_LGUI, LNAV, C_SMOUS, RENTR, LNUM, RALTD
//`-----------------------------' `-----------------------'
),
[_NUM] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_ESC, S(KC_8), KC_7, KC_8, KC_9, KC_SLSH, KC_BSLS, S(KC_9), S(KC_0), S(KC_BSLS), KC_TRNS, KC_BSPC,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_LCTL, KC_MINS, KC_4, KC_5, KC_6, S(KC_EQL), S(KC_5), KC_LBRC, KC_RBRC, S(KC_SCLN), KC_SCLN, KC_QUOT,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_LSFT, KC_GRV, KC_1, KC_2, KC_3, KC_EQL, KC_LBRC, KC_RBRC, KC_TRNS, KC_TRNS, KC_TRNS, KC_RSFT,
//|--------+--------+--------+--------+--------+----------+---------| |--------+--------+--------+--------+-----------+--------+--------|
KC_TRNS, KC_0, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
//`-----------------------------' `--------------------------'
),
[_NAV] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO, KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, KC_NO, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_NO,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO, KC_NO, KC_NO, KC_COPY, KC_PSTE, KC_NO, KC_NO, KC_HOME, KC_END, KC_PGDN, KC_PGUP, KC_NO,
//|--------+--------+--------+--------+--------+----------+---------| |--------+--------+--------+--------+-----------+--------+--------|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
//`-----------------------------' `--------------------------'
),
[_MEDIA] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO, KC_MPRV, KC_VOLD, KC_MPLY, KC_VOLU, KC_MNXT , KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
//|--------+--------+--------+--------+--------+----------+---------| |--------+--------+--------+--------+-----------+--------+--------|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
//`-----------------------------' `--------------------------'
),
[_FUNC] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_F11 ,KC_F12 ,KC_F13 ,KC_F14, KC_F15 , KC_TRNS, KC_TRNS ,KC_TRNS ,KC_TRNS ,KC_TRNS ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO , KC_F6 ,KC_F7 ,KC_F8 ,KC_F9, KC_F10 , KC_TRNS ,KC_RSFT ,KC_RCTL ,KC_RALT ,KC_RGUI ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 , KC_F5 , KC_TRNS ,KC_TRNS , KC_TRNS,KC_TRNS ,KC_TRNS, KC_NO ,
//|--------+--------+--------+--------+--------+----------+---------| |--------+--------+--------+--------+-----------+--------+--------|
KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS ,KC_TRNS ,KC_TRNS
//`-----------------------------' `--------------------------'
),
[_MOUS] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_LSFT ,KC_LALT ,KC_NO ,KC_NO ,KC_NO , KC_NO ,C_MINC ,C_MDEC ,KC_NO ,KC_NO ,C_MTOGG ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_LCTL ,MS_BTN3 ,MS_BTN2 ,MS_BTN1 ,KC_NO , KC_NO ,KC_RSFT ,KC_RCTL ,KC_RALT ,KC_RGUI ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_LGUI ,KC_NO ,KC_NO ,C_DRAG ,KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------+---------| |--------+--------+--------+--------+-----------+--------+--------|
KC_TRNS ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO
//`-----------------------------' `--------------------------'
),
[_CUST] = LAYOUT_4x6(
//,-------------------------------------------------------. ,--------------------------------------------------------.
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------| |--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO , KC_NO , KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,
//|--------+--------+--------+--------+--------+----------+---------| |--------+--------+--------+--------+-----------+--------+--------|
KC_NO ,KC_NO ,KC_NO , KC_NO ,KC_NO , KC_NO
//`-----------------------------' `--------------------------'
)
};
// clang-format on
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
switch (keycode) {
case RSFT_T(KC_LBRC):
if (record->tap.count && record->event.pressed) {
tap_code16(S(KC_LBRC));
return false;
}
break;
case RCTL_T(KC_RBRC):
if (record->tap.count && record->event.pressed) {
tap_code16(S(KC_RBRC));
return false;
}
break;
case C_MINC:
if (record->event.pressed) {
change_pointer_dpi(&global_user_config, true);
debug_config_to_console(&global_user_config);
return false;
}
break;
case C_MDEC:
if (record->event.pressed) {
change_pointer_dpi(&global_user_config, false);
debug_config_to_console(&global_user_config);
return false;
}
break;
case C_MTOGG:
if (record->event.pressed) {
bool current_state = get_auto_mouse_enable();
set_auto_mouse_enable(!current_state);
return false;
}
break;
case C_DRAG:
if (record->event.pressed) {
set_scrolling = record->event.pressed;
return true;
}
break;
}
return true;
}

View File

@ -0,0 +1,3 @@
COMBO_ENABLE = no
CAPS_WORD_ENABLE = yes
DEFERRED_EXEC_ENABLE = yes

View File

@ -0,0 +1,25 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/*
* OLED
*/
#define I2C_DRIVER I2CD1
#define I2C1_SCL_PIN GP15
#define I2C1_SDA_PIN GP14

View File

@ -0,0 +1,71 @@
{
"keyboard_name": "Crosses 4x6 rev1",
"matrix_pins": {
"cols": ["GP13", "GP26", "GP22", "GP21", "GP23", "GP20"],
"rows": ["GP12", "GP27", "GP28", "GP29", "GP9"]
},
"usb": {
"device_version": "0.3.0",
"pid": "0x5649"
},
"layouts": {
"LAYOUT_4x6": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 1},
{"matrix": [0, 1], "x": 1, "y": 1},
{"matrix": [0, 2], "x": 2, "y": 0.5},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0.25},
{"matrix": [0, 5], "x": 5, "y": 0.5},
{"matrix": [5, 5], "x": 8.25, "y": 0.5},
{"matrix": [5, 4], "x": 9.25, "y": 0.25},
{"matrix": [5, 3], "x": 10.25, "y": 0},
{"matrix": [5, 2], "x": 11.25, "y": 0.5},
{"matrix": [5, 1], "x": 12.25, "y": 1},
{"matrix": [5, 0], "x": 13.25, "y": 1},
{"matrix": [1, 0], "x": 0, "y": 2},
{"matrix": [1, 1], "x": 1, "y": 2},
{"matrix": [1, 2], "x": 2, "y": 1.5},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.5},
{"matrix": [6, 5], "x": 8.25, "y": 1.5},
{"matrix": [6, 4], "x": 9.25, "y": 1.25},
{"matrix": [6, 3], "x": 10.25, "y": 1},
{"matrix": [6, 2], "x": 11.25, "y": 1.5},
{"matrix": [6, 1], "x": 12.25, "y": 2},
{"matrix": [6, 0], "x": 13.25, "y": 2},
{"matrix": [2, 0], "x": 0, "y": 3},
{"matrix": [2, 1], "x": 1, "y": 3},
{"matrix": [2, 2], "x": 2, "y": 2.5},
{"matrix": [2, 3], "x": 3, "y": 2},
{"matrix": [2, 4], "x": 4, "y": 2.25},
{"matrix": [2, 5], "x": 5, "y": 2.5},
{"matrix": [7, 5], "x": 8.25, "y": 2.5},
{"matrix": [7, 4], "x": 9.25, "y": 2.25},
{"matrix": [7, 3], "x": 10.25, "y": 2},
{"matrix": [7, 2], "x": 11.25, "y": 2.5},
{"matrix": [7, 1], "x": 12.25, "y": 3},
{"matrix": [7, 0], "x": 13.25, "y": 3},
{"matrix": [3, 0], "x": 0, "y": 4},
{"matrix": [3, 1], "x": 1, "y": 4},
{"matrix": [3, 2], "x": 2, "y": 3.5},
{"matrix": [3, 3], "x": 3, "y": 3},
{"matrix": [3, 4], "x": 4, "y": 3.25},
{"matrix": [3, 5], "x": 5, "y": 3.5},
{"matrix": [8, 5], "x": 8.25, "y": 3.5},
{"matrix": [8, 4], "x": 9.25, "y": 3.25},
{"matrix": [8, 3], "x": 10.25, "y": 3},
{"matrix": [8, 2], "x": 11.25, "y": 3.5},
{"matrix": [8, 1], "x": 12.25, "y": 4},
{"matrix": [8, 0], "x": 13.25, "y": 4},
{"matrix": [4, 3], "x": 3, "y": 5.25},
{"matrix": [4, 4], "x": 4, "y": 5.25},
{"matrix": [4, 5], "x": 5, "y": 5.25},
{"matrix": [9, 5], "x": 8.25, "y": 5.25},
{"matrix": [9, 4], "x": 9.25, "y": 5.25},
{"matrix": [9, 3], "x": 10.25, "y": 5.25}
]
}
}
}

View File

@ -0,0 +1,22 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 TRUE

View File

@ -0,0 +1 @@
POINTING_DEVICE_DRIVER = pmw3360

View File

@ -0,0 +1,25 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/*
* OLED
*/
#define I2C_DRIVER I2CD0
#define I2C1_SDA_PIN GP8
#define I2C1_SCL_PIN GP9

View File

@ -0,0 +1,71 @@
{
"keyboard_name": "Crosses 4x6 rev2",
"matrix_pins": {
"cols": ["GP13", "GP26", "GP22", "GP21", "GP23", "GP20"],
"rows": ["GP5", "GP27", "GP28", "GP29", "GP7"]
},
"usb": {
"device_version": "0.3.0",
"pid": "0x5659"
},
"layouts": {
"LAYOUT_4x6": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 1},
{"matrix": [0, 1], "x": 1, "y": 1},
{"matrix": [0, 2], "x": 2, "y": 0.5},
{"matrix": [0, 3], "x": 3, "y": 0},
{"matrix": [0, 4], "x": 4, "y": 0.25},
{"matrix": [0, 5], "x": 5, "y": 0.5},
{"matrix": [5, 5], "x": 8.25, "y": 0.5},
{"matrix": [5, 4], "x": 9.25, "y": 0.25},
{"matrix": [5, 3], "x": 10.25, "y": 0},
{"matrix": [5, 2], "x": 11.25, "y": 0.5},
{"matrix": [5, 1], "x": 12.25, "y": 1},
{"matrix": [5, 0], "x": 13.25, "y": 1},
{"matrix": [1, 0], "x": 0, "y": 2},
{"matrix": [1, 1], "x": 1, "y": 2},
{"matrix": [1, 2], "x": 2, "y": 1.5},
{"matrix": [1, 3], "x": 3, "y": 1},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.5},
{"matrix": [6, 5], "x": 8.25, "y": 1.5},
{"matrix": [6, 4], "x": 9.25, "y": 1.25},
{"matrix": [6, 3], "x": 10.25, "y": 1},
{"matrix": [6, 2], "x": 11.25, "y": 1.5},
{"matrix": [6, 1], "x": 12.25, "y": 2},
{"matrix": [6, 0], "x": 13.25, "y": 2},
{"matrix": [2, 0], "x": 0, "y": 3},
{"matrix": [2, 1], "x": 1, "y": 3},
{"matrix": [2, 2], "x": 2, "y": 2.5},
{"matrix": [2, 3], "x": 3, "y": 2},
{"matrix": [2, 4], "x": 4, "y": 2.25},
{"matrix": [2, 5], "x": 5, "y": 2.5},
{"matrix": [7, 5], "x": 8.25, "y": 2.5},
{"matrix": [7, 4], "x": 9.25, "y": 2.25},
{"matrix": [7, 3], "x": 10.25, "y": 2},
{"matrix": [7, 2], "x": 11.25, "y": 2.5},
{"matrix": [7, 1], "x": 12.25, "y": 3},
{"matrix": [7, 0], "x": 13.25, "y": 3},
{"matrix": [3, 0], "x": 0, "y": 4},
{"matrix": [3, 1], "x": 1, "y": 4},
{"matrix": [3, 2], "x": 2, "y": 3.5},
{"matrix": [3, 3], "x": 3, "y": 3},
{"matrix": [3, 4], "x": 4, "y": 3.25},
{"matrix": [3, 5], "x": 5, "y": 3.5},
{"matrix": [8, 5], "x": 8.25, "y": 3.5},
{"matrix": [8, 4], "x": 9.25, "y": 3.25},
{"matrix": [8, 3], "x": 10.25, "y": 3},
{"matrix": [8, 2], "x": 11.25, "y": 3.5},
{"matrix": [8, 1], "x": 12.25, "y": 4},
{"matrix": [8, 0], "x": 13.25, "y": 4},
{"matrix": [4, 3], "x": 3, "y": 5.25},
{"matrix": [4, 4], "x": 4, "y": 5.25},
{"matrix": [4, 5], "x": 5, "y": 5.25},
{"matrix": [9, 5], "x": 8.25, "y": 5.25},
{"matrix": [9, 4], "x": 9.25, "y": 5.25},
{"matrix": [9, 3], "x": 10.25, "y": 5.25}
]
}
}
}

View File

@ -0,0 +1,25 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C0
#define RP_I2C_USE_I2C0 TRUE
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 FALSE

View File

@ -0,0 +1 @@
POINTING_DEVICE_DRIVER = pmw3389

View File

@ -0,0 +1,85 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define SERIAL_PIO_USE_PIO1
/******************************************************************
* Trackball Setup
******************************************************************/
// Enable if you have a trackball
#define SPLIT_POINTING_ENABLE
/*
* Undomment ONLY ONE of the following defines
*/
// Using a single trackball on the right hand side
// #define POINTING_DEVICE_RIGHT
// Using a sinble trackball on the left hand side
// #define POINTING_DEVICE_LEFT
// Rocking dual trackballs!
#define POINTING_DEVICE_COMBINED
#ifdef POINTING_DEVICE_COMBINED
# define POINTING_DEVICE_INVERT_Y_RIGHT
#endif // POINTING_DEVICE_COMBINED
//
#ifdef POINTING_DEVICE_RIGHT
# define POINTING_DEVICE_INVERT_Y
#endif // POINTING_DEVICE_RIGHT
#define POINTING_DEVICE_TASK_THROTTLE_MS 10
#define POINTING_DEVICE_AUTO_MOUSE_ENABLE
#define AUTO_MOUSE_TIME 600
#define MASTER_RIGHT
#define SPI_SCK_PIN GP2
#define SPI_MOSI_PIN GP3
#define SPI_MISO_PIN GP0
#define PMW33XX_CS_PIN GP6
#define PMW33XX_LIFTOFF_DISTANCE 0x02
#define MOUSE_EXTENDED_REPORT
#define WHEEL_EXTENDED_REPORT
#define POINTING_DEVICE_DEBUG
#define SCROLL_DIVISOR_H 30.0
#define SCROLL_DIVISOR_V 30.0
/*
* Reset
*/
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP17
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 1000U
#define PERMISSIVE_HOLD
#define QUICK_TAP_TERM_PER_KEY
/*
* Font
*/
#define OLED_FONT_H "crosses-font.c"
/*
* Sync
*/
#define SPLIT_TRANSACTION_IDS_KB CROSSES_SECONDARY_SYNC_ID

View File

@ -0,0 +1,244 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.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 "progmem.h"
static const unsigned char PROGMEM font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0x7C, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0x7C, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC,
0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00,
0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E,
0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B,
0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00,
0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE,
0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x80, 0x80, 0x80, 0xF8,
0xF8, 0xF8, 0x80, 0x80, 0x80, 0x80,
0x00, 0x00, 0x00, 0xE0, 0xF0, 0xF8,
0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0x38, 0x78, 0x70, 0x60, 0x00,
0x00, 0xF8, 0xF8, 0xF8, 0x38, 0x38,
0x38, 0x38, 0x38, 0xB8, 0xF8, 0xF0,
0xE0, 0x00, 0xE0, 0xF0, 0xF8, 0x38,
0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0xF8, 0xF0, 0xE0, 0x00, 0x00,
0xF0, 0xF8, 0xF8, 0xB8, 0xB8, 0xB8,
0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0x00,
0x00, 0x00, 0xE0, 0xF0, 0xF8, 0xB8,
0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
0xB8, 0x38, 0x00, 0x00, 0xB8, 0xB8,
0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8,
0xB8, 0xB8, 0xB8, 0x38, 0x00, 0x00,
0xE0, 0xF0, 0xF8, 0xB8, 0xB8, 0xB8,
0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00,
0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F,
0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00,
0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20,
0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00,
0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F,
0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x03, 0x03, 0x03, 0x3B,
0x3B, 0x3B, 0x03, 0x03, 0x03, 0x03,
0x00, 0x00, 0x00, 0x0B, 0x1B, 0x3B,
0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0x38, 0x3C, 0x1C, 0x0C, 0x00,
0x00, 0x3B, 0x3B, 0x3B, 0x03, 0x03,
0x03, 0x0B, 0x1B, 0x3B, 0x39, 0x31,
0x20, 0x00, 0x0B, 0x1B, 0x3B, 0x38,
0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
0x38, 0x3B, 0x1B, 0x0B, 0x00, 0x00,
0x39, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B,
0x3B, 0x3B, 0x3B, 0x3B, 0x3F, 0x1F,
0x0E, 0x00, 0x38, 0x39, 0x3B, 0x3B,
0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B,
0x3F, 0x1F, 0x0E, 0x00, 0x0F, 0x1F,
0x3F, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B,
0x3B, 0x3B, 0x3B, 0x38, 0x38, 0x00,
0x00, 0x39, 0x3B, 0x3B, 0x3B, 0x3B,
0x3B, 0x3B, 0x3B, 0x3B, 0x3F, 0x1F,
0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@ -0,0 +1,282 @@
/*
This is the c library for EEPROM and other Crosses features.
You should not need to modify it as config comes from config.h
Copyright 2024 Vincent Franco <me@vincentfranco.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 "crosses.h"
#include "transactions.h"
#ifdef CONSOLE_ENABLE
# include "print.h"
#endif /* ifdef CONSOLE_ENABLE */
bool set_scrolling = false;
float scroll_acc_h = 0.0;
float scroll_acc_v = 0.0;
const uint16_t MIN_DEFAULT_DPI = 100;
const uint16_t MAX_DEFAULT_DPI = 10000;
/***********************************************************************
* Pointer Stroage
***********************************************************************/
global_user_config_t global_user_config = {0};
void write_config_to_eeprom(global_user_config_t* config) {
eeconfig_update_kb(config->raw);
}
uint16_t get_pointer_dpi(global_user_config_t* config) {
uint16_t current = config->mse_cpi;
if (current < MIN_DEFAULT_DPI) {
return MIN_DEFAULT_DPI;
}
if (current > MAX_DEFAULT_DPI) {
return MAX_DEFAULT_DPI;
}
return current;
}
void update_pointer_cpi(global_user_config_t* config) {
#ifdef POINTING_DEVICE_COMBINED
pointing_device_set_cpi_on_side(true, 1000);
pointing_device_set_cpi_on_side(false, get_pointer_dpi(config));
#endif /* ifdef POINTING_DEVICE_COMBINED */
#if defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
pointing_device_set_cpi(get_pointer_dpi(config));
#endif /* LEFT || RIGHT */
}
void change_pointer_dpi(global_user_config_t* config, bool inc) {
uint16_t current = config->mse_cpi;
uint16_t requested = current += inc ? 50 : -50;
if (requested < MIN_DEFAULT_DPI) {
#ifdef CONSOLE_ENABLE
dprintf("%u is beyond bounds - omitting operation", requested);
#endif // CONSOLE_ENABLE
return;
}
if (requested > MAX_DEFAULT_DPI) {
#ifdef CONSOLE_ENABLE
dprintf("%u is beyond bounds - omitting operation", requested);
#endif // CONSOLE_ENABLE
return;
}
config->mse_cpi = requested;
#ifdef POINTING_DEVICE_COMBINED
pointing_device_set_cpi_on_side(false, get_pointer_dpi(config));
#endif /* ifdef POINTING_DEVICE_COMBINED */
#if defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
pointing_device_set_cpi(get_pointer_dpi(config));
#endif /* ifdef POINTING_DEVICE_* */
write_config_to_eeprom(&global_user_config);
}
void debug_config_to_console(global_user_config_t* config) {
#ifdef CONSOLE_ENABLE
dprintf("(crosses) process_record_user: config = {\n"
"\traw = 0x%lu,\n"
"\t{\n"
"\t\tmse_cpi=0x%X (%u)\n"
"\t}\n"
"}\n",
(unsigned long)config->raw, config->mse_cpi, get_pointer_dpi(config));
#endif // CONSOLE_ENABLE
}
void eeconfig_init_kb(void) {
global_user_config.raw = 0;
global_user_config.mse_cpi = 400;
write_config_to_eeprom(&global_user_config);
debug_config_to_console(&global_user_config);
eeconfig_init_user();
}
/***********************************************************************
* Single Trackball Config
***********************************************************************/
#if defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_LEFT)
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
if (set_scrolling) {
// Calculate and accumulate scroll values based on mouse movement and divisors
scroll_acc_h += (float)mouse_report.x / SCROLL_DIVISOR_H;
scroll_acc_v += (float)mouse_report.y / SCROLL_DIVISOR_V;
// Assign integer parts of accumulated scroll values to the mouse report
mouse_report.h = (int16_t)scroll_acc_h;
mouse_report.v = (int16_t)scroll_acc_v;
// Update accumulated scroll values by subtracting the integer parts
scroll_acc_h -= (int16_t)scroll_acc_h;
scroll_acc_v -= (int16_t)scroll_acc_v;
// Clear the X and Y values of the mouse report
mouse_report.x = 0;
mouse_report.y = 0;
}
return pointing_device_task_user(mouse_report);
}
#endif /* RIGHT || LEFT */
/***********************************************************************
* Dual Trackball Config
***********************************************************************/
#ifdef POINTING_DEVICE_COMBINED
report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report) {
// Calculate and accumulate scroll values based on mouse movement and divisors
scroll_acc_h += (float)left_report.x / SCROLL_DIVISOR_H;
scroll_acc_v += (float)left_report.y / SCROLL_DIVISOR_V;
// Assign integer parts of accumulated scroll values to the mouse report
left_report.h = (int16_t)scroll_acc_h;
left_report.v = (int16_t)scroll_acc_v;
// Update accumulated scroll values by subtracting the integer parts
scroll_acc_h -= (int16_t)scroll_acc_h;
scroll_acc_v -= (int16_t)scroll_acc_v;
// Clear the X and Y values of the mouse report
left_report.x = 0;
left_report.y = 0;
return pointing_device_combine_reports(left_report, right_report);
}
#endif /* ifdef POINTING_DEVICE_COMBINED */
layer_state_t layer_state_set_kb(layer_state_t state) {
#if defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_LEFT)
if (get_highest_layer(state) != 5) {
set_scrolling = false;
}
#endif /* ifndef POINTING_DEVICE_* */
return layer_state_set_user(state);
}
void secondary_sync_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
if (in_buflen == sizeof(global_user_config)) {
memcpy(&global_user_config, in_data, sizeof(global_user_config));
}
}
void housekeeping_task_kb(void) {
if (!is_keyboard_master()) {
return;
}
static global_user_config_t last_config = {0};
static uint32_t last_sync = 0;
bool should_sync = false;
if (memcmp(&global_user_config, &last_config, sizeof(global_user_config))) {
should_sync = true;
memcpy(&last_config, &global_user_config, sizeof(global_user_config));
}
should_sync = (timer_elapsed32(last_sync) > 500);
if (!should_sync) {
return;
}
if (transaction_rpc_send(CROSSES_SECONDARY_SYNC_ID, sizeof(global_user_config), &global_user_config)) {
last_sync = timer_read32();
}
}
void keyboard_post_init_kb(void) {
global_user_config.raw = eeconfig_read_kb();
transaction_register_rpc(CROSSES_SECONDARY_SYNC_ID, secondary_sync_handler);
#if defined(POINTING_DEVICE_COMBINED) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_LEFT)
update_pointer_cpi(&global_user_config);
#endif /* ifdef POINTING_DEVICE_* */
write_config_to_eeprom(&global_user_config);
keyboard_post_init_user();
}
#ifdef OLED_ENABLE
oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
if (!is_keyboard_master()) {
return OLED_ROTATION_180;
}
return rotation;
}
# if defined(POINTING_DEVICE_COMBINED) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_LEFT)
void pointing_device_init_kb(void) {
set_auto_mouse_layer(5);
set_auto_mouse_enable(false);
}
# endif /* ifdef POINTING_DEVICE */
static void render_logo(void) {
static const char PROGMEM qmk_logo[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00};
oled_write_P(qmk_logo, false);
}
bool oled_task_kb(void) {
render_logo();
// clang-format off
const char* layer_names[] = {
[0] = "BASE CPI: ",
[1] = "PROG CPI: ",
[2] = "NAVI CPI: ",
[3] = "MEDIA CPI: ",
[4] = "FUNC CPI: ",
[5] = "MOUSE CPI: ",
};
// clang-format on
char cpi_str[6];
uint16_t current_dpi = get_pointer_dpi(&global_user_config);
snprintf(cpi_str, sizeof(cpi_str), "%u", (unsigned int)current_dpi);
oled_write(PSTR(layer_names[get_highest_layer(layer_state)]), false);
oled_write(cpi_str, false);
return false;
}
#endif /* ifdef OLED_ENABLE */

View File

@ -0,0 +1,53 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
/*
* Pointer Storage
*/
typedef union {
uint32_t raw;
struct {
uint16_t mse_cpi : 16;
} __attribute__((packed));
} global_user_config_t;
extern global_user_config_t global_user_config;
extern const uint16_t MIN_DEFAULT_DPI;
extern const uint16_t MAX_DEFAULT_DPI;
void write_config_to_eeprom(global_user_config_t* config);
uint16_t get_pointer_dpi(global_user_config_t* config);
void update_pointer_cpi(global_user_config_t* config);
void change_pointer_dpi(global_user_config_t* config, bool inc);
void debug_config_to_console(global_user_config_t* config);
/*
* Pointing Device Config
*/
extern bool set_scrolling;
extern float scroll_acc_h;
extern float scroll_acc_v;

View File

@ -0,0 +1,25 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define HAL_USE_I2C TRUE
#define HAL_USE_SPI TRUE
#define SPI_USE_WAIT TRUE
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
#include_next <halconf.h>

View File

@ -0,0 +1,28 @@
{
"bootloader": "rp2040",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"command": false,
"console": true,
"extrakey": true,
"mousekey": true,
"nkro": true,
"oled": true,
"pointing_device": true
},
"processor": "RP2040",
"split": {
"enabled": true,
"serial": {
"driver": "vendor",
"pin": "GP4"
},
"transport": {
"sync": {
"layer_state": true,
"matrix_state": true
}
}
}
}

View File

@ -0,0 +1,23 @@
/*
Copyright 2025 Vincent Franco <me@vincentfranco.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include_next <mcuconf.h>
#undef RP_SPI_USE_SPI0
#define RP_SPI_USE_SPI0 TRUE

View File

@ -0,0 +1,46 @@
# Crosses by Good Great Grand Wonderful
![crosses](https://i.imgur.com/LWiT2bD.png)
Our thumbs evolved to give us dexterity; shouldn't our keyboards evolve with them?
* Keyboard Maintainer: [Good Great Grand Wonderful LLC](https://github.com/Good-Great-Grand-Wonderful)
* Hardware Supported:
* Matrix configurations in: 3x5, 3x6, 4x6 boards with a three key thumb cluster.
* Trackballs!
* OLED Displays
* Any SPI / I2C breakout using a 6P JST SH for SPI and a 2.54mm breakout for I2C.
* Hardware Availability: https://ergokeyboards.com
### Compiling (after setting up your build environment):
```bash
qmk compile -kb gggw/crosses/<LAYOUT>/<REV> -km default
```
### Flashing example for this keyboard:
```bash
qmk flash -kb gggw/crosses/<LAYOUT>/<REV> -km default
```
#### Concrete example:
`<LAYOUT>` is one of 3x5, 3x6, 4x6
`<REV>` is the firmware required for your thumbclusters which is one of: rev1, rev2
Flashing a 3x6 revision 2 model
```bash
qmk comfile -kb gggw/crosses/3x6/rev2 -km default
```
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader one of two ways:
* **Physical reset button**: Double-tap the reset button on the RP2040
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

8
keyboards/gggw/info.json Normal file
View File

@ -0,0 +1,8 @@
{
"manufacturer": "Good Great Grand Wonderful",
"maintainer": "Vincent Franco",
"url": "https://ergokeyboards.com",
"usb": {
"vid": "0x3034"
}
}