Compare commits

...

28 Commits

Author SHA1 Message Date
Mark Stosberg
39d490f39e
Merge d382503975 into 9bea332a21 2024-11-20 22:22:13 -08:00
Ryan
9bea332a21
qmk via2json: Improve macro parsing (#24345) 2024-11-21 17:20:05 +11:00
Ryan
8cbcdcac62
qmk new-keymap: validate keymap name (#23420) 2024-11-21 17:18:51 +11:00
Mark Stosberg
d382503975
fixup: recommended change from drashna 2024-11-13 20:27:09 -05:00
Mark Stosberg
37218327c6
linting: qmk format-c on matrix.c
No other changes
2024-11-13 20:25:01 -05:00
Mark Stosberg
25a4d5fb86
fixup: move OLED task logic from default keyboard to keyboard level.
Thanks to @drasha suggestion.
2024-11-13 20:22:51 -05:00
Mark Stosberg
7c34400288
fixup: Update vid to be unique. 2024-11-13 20:22:51 -05:00
Yudai NAKATA
f987a86db4
fix: fix incorrect pin assignments 2024-11-13 20:22:51 -05:00
Mark Stosberg
44f6e22684
fixup: quite disabling Space Cadet
There's room for it now in the RP2040 storage.
2024-11-13 20:22:51 -05:00
Mark Stosberg
5ad0ccc09a
Update config.h
Co-authored-by: Joel Challis <git@zvecr.com>
2024-11-13 20:22:51 -05:00
Mark Stosberg
636b95ab85
WIP: getting rid of CONVERT_TO
Encoder and lights are currently not working correctly.
2024-11-13 20:22:51 -05:00
Mark Stosberg
8d6b3409cc
BugFixes: Typing, switch to RP2040 & sprintf
- The angle of -30 was not displaying correctly with unsigned type
- Explicitly cast a result to a double for consistent typing
- The code without snprintf didn't work. Revert to snprintf, but also
  switch to RP2040 which has room for it.
2024-11-13 20:22:50 -05:00
Mark Stosberg
b2ab70d23a
fixup: comment, whitespace 2024-11-13 20:22:50 -05:00
Mark Stosberg
c7c04c1ce5
refinemts: OLED is working better, but new problems.
Now the OLED display is no longer scrambled, but there are two new problems with it:

 1. The number "506" is printed over the design
 2. The screen never refreshes. As originally submitted, the OLED
    would update to reflect layer changes.
2024-11-13 20:22:50 -05:00
Mark Stosberg
a4ba098668
fixup: make sure custom matrix code is loaded 2024-11-13 20:22:50 -05:00
Mark Stosberg
a9fec768c0
Re-enable OLED. Was not working before.
But now it displays a random pattern instead of soemthing useful
2024-11-13 20:22:50 -05:00
Mark Stosberg
154b9efd6a
docs: Refine docs 2024-11-13 20:22:50 -05:00
Mark Stosberg
a2605f9953
fixup: remove necesesary DIODE_DIRECTION due to custom matrix code 2024-11-13 20:22:50 -05:00
Mark Stosberg
a97ebfef8a
fixup: remove apparently unnecessary MOUSEKEY section and re-indent 2024-11-13 20:22:50 -05:00
Mark Stosberg
b0fad57a30
fixup: remove unnecesssary header include 2024-11-13 20:22:50 -05:00
Mark Stosberg
48f99880c5
refinements: right half no longer works
After this round of refinements, the left half of keyboard and the
pointing device work, but no keycodes are emitted from the right half
at all.
2024-11-13 20:22:50 -05:00
Mark Stosberg
742049b8bc
code review suggestions: use alternate functions in matrix.c
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-11-13 20:22:50 -05:00
Mark Stosberg
61960ab4d1
minimize includes in cocot46plus.c
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-11-13 20:22:49 -05:00
Mark Stosberg
20ec3767c9
simplify layer definitions
Co-authored-by: Ryan <fauxpark@gmail.com>
2024-11-13 20:22:49 -05:00
Mark Stosberg
56d3759893
encoders: use encoder_map instead of custom code 2024-11-13 20:22:49 -05:00
Mark Stosberg
123b5b4ed9
remove unnecessary custom_lite key 2024-11-13 20:22:49 -05:00
Mark Stosberg
08d28e037b
Apply suggestions from code review
Co-authored-by: Joel Challis <git@zvecr.com>
Co-authored-by: jack <0x6a73@protonmail.com>
2024-11-13 20:22:49 -05:00
Mark Stosberg
8bd2c19129
[Keyboard] add aki27/cocot46plus 2024-11-13 20:22:49 -05:00
11 changed files with 1078 additions and 9 deletions

View File

@ -0,0 +1,289 @@
/*
Copyright 2022 aki27
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 QMK_KEYBOARD_H
#include <math.h>
// Invert vertical scroll direction
#ifndef COCOT_SCROLL_INV_DEFAULT
# define COCOT_SCROLL_INV_DEFAULT 1
#endif
// All the default values here refer to O-based array indexes
// not actual values
#ifndef COCOT_CPI_OPTIONS
# define COCOT_CPI_OPTIONS { 250, 500, 750, 1000, 1250 }
#endif
#ifndef COCOT_CPI_DEFAULT
# define COCOT_CPI_DEFAULT 4
#endif
#ifndef COCOT_SCROLL_DIVIDERS
# define COCOT_SCROLL_DIVIDERS { 1, 2, 3, 4, 5, 6 }
#endif
#ifndef COCOT_SCROLL_DIV_DEFAULT
# define COCOT_SCROLL_DIV_DEFAULT 4
#endif
#ifndef COCOT_ROTATION_ANGLE
# define COCOT_ROTATION_ANGLE { -60, -45, -30, -15, 0, 15, 30, 45, 60 }
#endif
#ifndef COCOT_ROTATION_DEFAULT
# define COCOT_ROTATION_DEFAULT 2
#endif
cocot_config_t cocot_config;
uint16_t cpi_array[] = COCOT_CPI_OPTIONS;
uint16_t scrl_div_array[] = COCOT_SCROLL_DIVIDERS;
int8_t angle_array[] = COCOT_ROTATION_ANGLE;
#define CPI_OPTION_SIZE (sizeof(cpi_array) / sizeof(uint16_t))
#define SCRL_DIV_SIZE (sizeof(scrl_div_array) / sizeof(uint16_t))
#define ANGLE_SIZE (sizeof(angle_array) / sizeof(int8_t))
// Trackball State
bool BurstState = false; // init burst state for Trackball module
uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
// Scroll Accumulation
static int16_t h_acm = 0;
static int16_t v_acm = 0;
void pointing_device_init_kb(void) {
// set the CPI.
pointing_device_set_cpi(cpi_array[cocot_config.cpi_idx]);
adns5050_write_reg(0x22, 0b10000 | 0x80);
}
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
double rad = (double)angle_array[cocot_config.rotation_angle] * (M_PI / 180) * -1;
int8_t x_rev = + mouse_report.x * cos(rad) - mouse_report.y * sin(rad);
int8_t y_rev = + mouse_report.x * sin(rad) + mouse_report.y * cos(rad);
if (cocot_get_scroll_mode()) {
// rock scroll direction
if (abs(x_rev) > abs(y_rev)) {
y_rev = 0;
} else {
x_rev = 0;
}
// accumulate scroll
h_acm += x_rev * cocot_config.scrl_inv;
v_acm += y_rev * cocot_config.scrl_inv * -1;
int8_t h_rev = h_acm >> scrl_div_array[cocot_config.scrl_div];
int8_t v_rev = v_acm >> scrl_div_array[cocot_config.scrl_div];
// clear accumulated scroll on assignment
if (h_rev != 0) {
if (mouse_report.h + h_rev > 127) {
h_rev = 127 - mouse_report.h;
} else if (mouse_report.h + h_rev < -127) {
h_rev = -127 - mouse_report.h;
}
mouse_report.h += h_rev;
h_acm -= h_rev << scrl_div_array[cocot_config.scrl_div];
}
if (v_rev != 0) {
if (mouse_report.v + v_rev > 127) {
v_rev = 127 - mouse_report.v;
} else if (mouse_report.v + v_rev < -127) {
v_rev = -127 - mouse_report.v;
}
mouse_report.v += v_rev;
v_acm -= v_rev << scrl_div_array[cocot_config.scrl_div];
}
mouse_report.x = 0;
mouse_report.y = 0;
} else {
mouse_report.x = x_rev;
mouse_report.y = y_rev;
}
return pointing_device_task_user(mouse_report);
}
bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
// xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed);
if (!process_record_user(keycode, record)) {
return false;
}
if (keycode == CPI_SW && record->event.pressed) {
cocot_config.cpi_idx = (cocot_config.cpi_idx + 1) % CPI_OPTION_SIZE;
eeconfig_update_kb(cocot_config.raw);
pointing_device_set_cpi(cpi_array[cocot_config.cpi_idx]);
}
if (keycode == SCRL_SW && record->event.pressed) {
cocot_config.scrl_div = (cocot_config.scrl_div + 1) % SCRL_DIV_SIZE;
eeconfig_update_kb(cocot_config.raw);
}
if (keycode == ROT_R15 && record->event.pressed) {
cocot_config.rotation_angle = (cocot_config.rotation_angle + 1) % ANGLE_SIZE;
eeconfig_update_kb(cocot_config.raw);
}
if (keycode == ROT_L15 && record->event.pressed) {
cocot_config.rotation_angle = (ANGLE_SIZE + cocot_config.rotation_angle - 1) % ANGLE_SIZE;
eeconfig_update_kb(cocot_config.raw);
}
if (keycode == SCRL_IN && record->event.pressed) {
cocot_config.scrl_inv = -cocot_config.scrl_inv;
eeconfig_update_kb(cocot_config.raw);
}
if (keycode == SCRL_TO && record->event.pressed) {
{
cocot_config.scrl_mode ^= 1;
}
}
if (keycode == SCRL_MO) {
{
cocot_config.scrl_mode ^= 1;
}
}
return true;
}
void eeconfig_init_kb(void) {
cocot_config.cpi_idx = COCOT_CPI_DEFAULT;
cocot_config.scrl_div = COCOT_SCROLL_DIV_DEFAULT;
cocot_config.rotation_angle = COCOT_ROTATION_DEFAULT;
cocot_config.scrl_inv = COCOT_SCROLL_INV_DEFAULT;
cocot_config.scrl_mode = false;
eeconfig_update_kb(cocot_config.raw);
eeconfig_init_user();
adns5050_write_reg(0x22, 0b10000 | 0x80);
}
void matrix_init_kb(void) {
// is safe to just read CPI setting since matrix init
// comes before pointing device init.
cocot_config.raw = eeconfig_read_kb();
if (cocot_config.cpi_idx > CPI_OPTION_SIZE) // || cocot_config.scrl_div > SCRL_DIV_SIZE || cocot_config.rotation_angle > ANGLE_SIZE)
{
eeconfig_init_kb();
}
matrix_init_user();
}
bool cocot_get_scroll_mode(void) {
return cocot_config.scrl_mode;
}
void cocot_set_scroll_mode(bool mode) {
cocot_config.scrl_mode = mode;
}
// OLED utility
#ifdef OLED_ENABLE
bool oled_task_kb(void) {
if (!oled_task_user()) {
return false;
}
render_logo();
oled_write_layer_state();
return false;
}
oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
return OLED_ROTATION_0;
}
static const char PROGMEM cocot_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,
0};
void render_logo(void) {
oled_write_P(cocot_logo, false);
};
void oled_write_layer_state(void) {
oled_write_P(PSTR(" "), false);
switch (get_highest_layer(layer_state | default_layer_state)) {
case 0:
oled_write_P(PSTR("Base "), false);
break;
case 1:
oled_write_P(PSTR("Lower"), false);
break;
case 2:
oled_write_P(PSTR("Raise"), false);
break;
case 3:
oled_write_P(PSTR("Mouse"), false);
break;
case 4:
oled_write_P(PSTR("L4 "), false);
break;
case 5:
oled_write_P(PSTR("L5 "), false);
break;
case 6:
oled_write_P(PSTR("L6 "), false);
break;
default:
oled_write_P(PSTR("Undef"), false);
break;
}
oled_write_P(PSTR("/"), false);
if (cocot_get_scroll_mode()){
oled_write_P(PSTR("S"), false);
} else{
oled_write_P(PSTR("C"), false);
}
char cpi[5];
char scroll_div[3];
char angle[4];
snprintf(cpi, 5, "%4d", cpi_array[cocot_config.cpi_idx]);
snprintf(scroll_div, 3, "%2d", scrl_div_array[cocot_config.scrl_div]);
snprintf(angle, 4, "%3d", angle_array[cocot_config.rotation_angle]);
oled_write_P(PSTR("/"), false);
oled_write(cpi, false);
oled_write_P(PSTR("/"), false);
oled_write(scroll_div, false);
oled_write_P(PSTR("/"), false);
oled_write(angle, false);
}
#endif

View File

@ -0,0 +1,41 @@
/*
Copyright 2022 aki27
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"
typedef union {
uint32_t raw;
struct {
uint8_t cpi_idx;
uint8_t scrl_div;
uint8_t rotation_angle;
int8_t scrl_inv;
bool scrl_mode;
report_mouse_t last_mouse;
};
} cocot_config_t;
extern cocot_config_t cocot_config;
bool cocot_get_scroll_mode(void);
void cocot_set_scroll_mode(bool mode);
void render_logo(void);
void oled_write_layer_state(void);

View File

@ -0,0 +1,33 @@
/*
Copyright 2022 aki27
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
// These do not seem to have keyboard.json support yet.
#define ADNS5050_SCLK_PIN GP23
#define ADNS5050_SDIO_PIN GP8
#define ADNS5050_CS_PIN GP9
#define I2C1_SDA_PIN GP2
#define I2C1_SCL_PIN GP3
/* key matrix size */
#define MATRIX_ROWS 10
#define MATRIX_COLS 6
#define POINTING_DEVICE_ROTATION_180
#define OLED_FONT_H "keyboards/aki27/cocot46plus/glcdfont.c"

View File

@ -0,0 +1,232 @@
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
// See gfxfont.h for newer custom bitmap font info.
#include "progmem.h"
// Standard ASCII 5x7 font
const unsigned char font[] PROGMEM = {
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, 0xC0, 0x60, 0xC0, 0xD0,
0xC8, 0xE8, 0x6C, 0x64, 0x64, 0x64,
0x6C, 0x68, 0x68, 0x98, 0xD0, 0x60,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xE0, 0xE0,
0x20, 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,
0xFC, 0x87, 0x78, 0xFE, 0xFE, 0x01,
0x01, 0x78, 0x84, 0x82, 0x02, 0x02,
0x86, 0x86, 0x03, 0x01, 0x87, 0xFF,
0xFC, 0x03, 0xFE, 0x00, 0x00, 0x00,
0x00, 0xFC, 0xFE, 0xCF, 0x03, 0x03,
0x03, 0x03, 0x87, 0xC7, 0x86, 0x00,
0x78, 0xFE, 0xFF, 0x87, 0x03, 0x03,
0x03, 0x03, 0xCF, 0xFE, 0xFC, 0x00,
0x38, 0xFE, 0xFF, 0x87, 0x03, 0x03,
0x03, 0x03, 0xC7, 0x86, 0x84, 0x00,
0xFC, 0xFE, 0x87, 0x03, 0x03, 0x03,
0x03, 0x87, 0xFE, 0xFC, 0x30, 0x03,
0x03, 0xFF, 0xFF, 0x83, 0x03, 0x00,
0x00, 0x70, 0x78, 0x7E, 0x6F, 0x63,
0x61, 0xFF, 0xFF, 0x60, 0x60, 0x00,
0xF0, 0xFC, 0xFF, 0x0F, 0x0F, 0x0E,
0x8E, 0xFC, 0xF8, 0x60, 0x00, 0x30,
0x30, 0x30, 0x30, 0x30, 0xFF, 0xFF,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
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, 0x04, 0x19, 0x3F, 0x27,
0x42, 0x58, 0x58, 0xD9, 0x99, 0x99,
0xD8, 0x5D, 0x5F, 0x6E, 0x2C, 0x19,
0x0C, 0x07, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x01, 0x00,
0x00, 0x01, 0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x01, 0x00, 0x00,
0x00, 0x00, 0x01, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x01, 0x00, 0x00,
0x00, 0x01, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x01, 0x03, 0x03, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x03, 0x00, 0x00, 0x00,
0x00, 0x01, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 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, 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,130 @@
{
"keyboard_name": "cocot46plus",
"manufacturer": "aki27",
"maintainer": "markstos",
"tags": ["unibody","ergo","corne","trackball","encoder","rgb"],
"usb": {
"device_version": "1.0.0",
"pid": "0x4600",
"vid": "0x4600"
},
"development_board": "promicro_rp2040",
"matrix_pins": {
"cols": ["GP29", "GP28", "GP27", "GP26", "GP22", "GP20"],
"rows": ["GP4", "GP5", "GP6", "GP7", "NO_PIN"]
},
"build": {
"lto": true
},
"features": {
"bootmagic": true,
"encoder": true,
"extrakey": true,
"mousekey": true,
"oled": true,
"pointing_device": true,
"rgblight": true
},
"ws2812": {
"pin": "GP21",
"driver": "vendor"
},
"encoder": {
"rotary": [
{ "pin_a": "GP0", "pin_b": "GP1"}
]
},
"rgblight": {
"led_count": 12,
"animations": {
"breathing": true,
"rainbow_mood": true,
"rainbow_swirl": true,
"snake": true,
"static_gradient": true,
"twinkle": true,
},
"hue_steps": 10,
"max_brightness": 120,
},
"keycodes":[
{"key": "CPI_SW"},
{"key": "SCRL_SW"},
{"key": "ROT_R15"},
{"key": "ROT_L15"},
{"key": "SCRL_MO"},
{"key": "SCRL_TO"},
{"key": "SCRL_IN"}
],
"layouts": {
"LAYOUT": {
"layout": [
{ "matrix": [0,0], "x": 0, "y": 0},
{ "matrix": [0,1], "x": 1, "y": 0},
{ "matrix": [0,2], "x": 2, "y": 0},
{ "matrix": [0,3], "x": 3, "y": 0},
{ "matrix": [0,4], "x": 4, "y": 0},
{ "matrix": [0,5], "x": 5, "y": 0},
{ "matrix": [5,5], "x": 9, "y": 0},
{ "matrix": [5,4], "x": 10, "y": 0},
{ "matrix": [5,3], "x": 11, "y": 0},
{ "matrix": [5,2], "x": 12, "y": 0},
{ "matrix": [5,1], "x": 13, "y": 0},
{ "matrix": [5,0], "x": 14, "y": 0},
{ "matrix": [1,0], "x": 0, "y": 1},
{ "matrix": [1,1], "x": 1, "y": 1},
{ "matrix": [1,2], "x": 2, "y": 1},
{ "matrix": [1,3], "x": 3, "y": 1},
{ "matrix": [1,4], "x": 4, "y": 1},
{ "matrix": [1,5], "x": 5, "y": 1},
{ "matrix": [6,5], "x": 9, "y": 1},
{ "matrix": [6,4], "x": 10, "y": 1},
{ "matrix": [6,3], "x": 11, "y": 1},
{ "matrix": [6,2], "x": 12, "y": 1},
{ "matrix": [6,1], "x": 13, "y": 1},
{ "matrix": [6,0], "x": 14, "y": 1},
{ "matrix": [2,0], "x": 0, "y": 2},
{ "matrix": [2,1], "x": 1, "y": 2},
{ "matrix": [2,2], "x": 2, "y": 2},
{ "matrix": [2,3], "x": 3, "y": 2},
{ "matrix": [2,4], "x": 4, "y": 2},
{ "matrix": [2,5], "x": 5, "y": 2},
{ "matrix": [7,5], "x": 9, "y": 2},
{ "matrix": [7,4], "x": 10, "y": 2},
{ "matrix": [7,3], "x": 11, "y": 2},
{ "matrix": [7,2], "x": 12, "y": 2},
{ "matrix": [7,1], "x": 13, "y": 2},
{ "matrix": [7,0], "x": 14, "y": 2},
{ "matrix": [3,0], "x": 2, "y": 3},
{ "matrix": [3,1], "x": 3, "y": 3},
{ "matrix": [3,2], "x": 4, "y": 3},
{ "matrix": [3,3], "x": 5, "y": 3},
{ "matrix": [3,5], "x": 6, "y": 3},
{ "matrix": [8,5], "x": 8, "y": 3},
{ "matrix": [8,3], "x": 9, "y": 3},
{ "matrix": [8,2], "x": 10, "y": 3},
{ "matrix": [8,1], "x": 11, "y": 3},
{ "matrix": [8,0], "x": 12, "y": 3},
{ "matrix": [4,2], "x": 6, "y": 4},
{ "matrix": [3,4], "x": 7, "y": 4},
{ "matrix": [4,4], "x": 8, "y": 4},
{ "matrix": [9,2], "x": 9, "y": 4},
{ "matrix": [8,4], "x": 10, "y": 4},
{ "matrix": [9,5], "x": 11, "y": 4},
]
}
}
}

View File

@ -0,0 +1,125 @@
/*
Copyright 2022 aki27
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 QMK_KEYBOARD_H
// Defines names for use in layer keycodes and the keymap
enum layer_number {
_BASE,
_LOWER,
_RAISE,
_TRACKBALL
};
#define LW_MHEN LT(1,KC_INT5) // lower
#define RS_HENK LT(2,KC_INT4) // raise
#define DEL_ALT ALT_T(KC_DEL)
// In the buttom row, KC_MS_BTN3 binds middle-click to the encoder's button press
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, 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_MINS,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LGUI, DEL_ALT, LW_MHEN, KC_SPC, KC_MS_BTN1, KC_MS_BTN2, KC_ENT, RS_HENK, KC_BSPC, KC_ESC,
XXXXXXX, KC_MS_BTN3, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
//`--------------' `--------------'
),
[_LOWER] = LAYOUT(
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_ESC, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, KC_COLN, KC_DQUO,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LSFT, KC_GRV, KC_TILD, KC_NUBS, KC_PIPE, XXXXXXX, KC_EQL, KC_PLUS, KC_LABK, KC_RABK, KC_QUES, KC_UNDS,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LGUI, DEL_ALT, KC_TRNS, KC_SPC, KC_MS_BTN4, KC_MS_BTN5, KC_ENT, TT(3), KC_BSPC, KC_ESC,
XXXXXXX, KC_MS_BTN3, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
//`--------------' `--------------'
),
[_RAISE] = LAYOUT(
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LCTL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_APP, KC_UP,S(KC_INT1), KC_UNDS, KC_DQUO, KC_COLN,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LSFT, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_LEFT, KC_DOWN, KC_RGHT, KC_DOT, KC_SLSH, KC_MINS,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LGUI, DEL_ALT, TT(3), KC_SPC, KC_MS_BTN4, KC_MS_BTN5, KC_ENT, KC_TRNS, KC_BSPC, KC_ESC,
XXXXXXX, KC_MS_BTN3, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
//`--------------' `--------------'
),
[_TRACKBALL] = LAYOUT(
//|-------------------------------------------------------| |-------------------------------------------------------|
QK_BOOT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_TOG, SCRL_TO, CPI_SW, SCRL_SW, ROT_L15, ROT_R15, XXXXXXX,
//|-------------------------------------------------------| |-------------------------------------------------------|
XXXXXXX, XXXXXXX, RGB_VAI, RGB_SAI, RGB_HUI, RGB_MOD, SCRL_MO, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
//|-------------------------------------------------------| |-------------------------------------------------------|
XXXXXXX, XXXXXXX, RGB_VAD, RGB_SAD, RGB_HUD,RGB_RMOD, SCRL_IN, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
//|-------------------------------------------------------| |-------------------------------------------------------|
KC_LGUI, DEL_ALT, KC_TRNS, KC_SPC, KC_MS_BTN1, KC_MS_BTN2, KC_ENT, RS_HENK, KC_BSPC, KC_ESC,
XXXXXXX, KC_MS_BTN3, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
//`--------------' `--------------'
)
};
// Same function on all layers for now.
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[0] = { ENCODER_CCW_CW(KC_PGUP, KC_PGDN) },
[1] = { ENCODER_CCW_CW(KC_PGUP, KC_PGDN) },
[2] = { ENCODER_CCW_CW(KC_PGUP, KC_PGDN) },
[3] = { ENCODER_CCW_CW(KC_PGUP, KC_PGDN) },
};
#endif
layer_state_t layer_state_set_user(layer_state_t state) {
switch (get_highest_layer(state)) {
case _LOWER:
#ifdef RGBLIGHT_ENABLE
rgblight_sethsv_range(HSV_BLUE, 0, 2);
#endif
cocot_set_scroll_mode(true);
break;
case _RAISE:
#ifdef RGBLIGHT_ENABLE
rgblight_sethsv_range(HSV_RED, 0, 2);
#endif
cocot_set_scroll_mode(true);
break;
case _TRACKBALL:
#ifdef RGBLIGHT_ENABLE
rgblight_sethsv_range(HSV_GREEN, 0, 2);
#endif
cocot_set_scroll_mode(false);
break;
default:
#ifdef RGBLIGHT_ENABLE
rgblight_sethsv_range( 0, 0, 0, 0, 2);
#endif
cocot_set_scroll_mode(false);
break;
}
#ifdef RGBLIGHT_ENABLE
rgblight_set_effect_range( 2, 10);
#endif
return state;
};

View File

@ -0,0 +1,143 @@
/*
Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
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 "matrix.h"
#include "wait.h"
static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
static void select_row(uint8_t row) {
gpio_set_pin_output(row_pins[row]);
gpio_write_pin_low(row_pins[row]);
}
static void unselect_row(uint8_t row) {
gpio_set_pin_input_high(row_pins[row]);
}
static void unselect_rows(void) {
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
gpio_set_pin_input_high(row_pins[x]);
}
}
static void select_col(uint8_t col) {
gpio_set_pin_output(col_pins[col]);
gpio_write_pin_low(col_pins[col]);
}
static void unselect_col(uint8_t col) {
gpio_set_pin_input_high(col_pins[col]);
}
static void unselect_cols(void) {
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
gpio_set_pin_input_high(col_pins[x]);
}
}
static void init_pins(void) {
unselect_rows();
unselect_cols();
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
gpio_set_pin_input_high(col_pins[x]);
}
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
gpio_set_pin_input_high(row_pins[x]);
}
}
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[current_row];
// Clear data in matrix row
current_matrix[current_row] = 0;
// Select row and wait for row selecton to stabilize
select_row(current_row);
wait_us(30);
// For each col...
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
// Select the col pin to read (active low)
uint8_t pin_state = gpio_read_pin(col_pins[col_index]);
// Populate the matrix row with the state of the col pin
current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
}
// Unselect row
unselect_row(current_row);
return (last_row_value != current_matrix[current_row]);
}
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
bool matrix_changed = false;
// Select col and wait for col selecton to stabilize
select_col(current_col);
wait_us(30);
// For each row...
for (uint8_t row_index = 0; row_index < MATRIX_ROWS / 2; row_index++) {
uint8_t tmp = row_index + MATRIX_ROWS / 2;
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[tmp];
// Check row pin state
if (gpio_read_pin(row_pins[row_index]) == 0) {
// Pin LO, set col bit
current_matrix[tmp] |= (MATRIX_ROW_SHIFTER << current_col);
} else {
// Pin HI, clear col bit
current_matrix[tmp] &= ~(MATRIX_ROW_SHIFTER << current_col);
}
// Determine if the matrix changed state
if ((last_row_value != current_matrix[tmp]) && !(matrix_changed)) {
matrix_changed = true;
}
}
// Unselect col
unselect_col(current_col);
return matrix_changed;
}
void matrix_init_custom(void) {
// initialize key pins
init_pins();
}
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
bool changed = false;
// Set row, read cols
for (uint8_t current_row = 0; current_row < MATRIX_ROWS / 2; current_row++) {
changed |= read_cols_on_row(current_matrix, current_row);
}
// else
// Set col, read rows
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
changed |= read_rows_on_col(current_matrix, current_col);
}
return (uint8_t)changed;
}

View File

@ -0,0 +1,45 @@
# cocot46plus
![cocot46plus_photo15](https://i.imgur.com/yCvbMgo.jpeg)
cocot46plus is a column-staggered keyboard with 46 keys, a 34mm-trackball and a rotary encoder.
- Keyboard Maintainer: [markstos](https://github.com/markstos)
- Hardware Supported: cocot46plus PCB, SparkFun Pro Micro - RP2040
- Hardware Availability: [Yushakobo.jp](https://shop.yushakobo.jp/en/products/6955)
Detailed information is available from the links below:
- [JP](https://www.notion.so/aki27/cocot46plus-55775bf44a664dae9d6ca342e79e8312)
- [EN](https://aki27.notion.site/cocot46plus-Introduction-e6261b0a5ce045f8a0d8535a74844929)
## Build Guides
- [JP](https://github.com/aki27kbd/cocot46plus/blob/main/doc/buildguide.md)
- [EN](https://github.com/aki27kbd/cocot46plus/blob/main/doc/v1/buildguide_en.md)
### Special keycodes
Value | Keycode |Description
---------|-----------|-----------
`0x5DA7` | `CPI_SW` |Switch CPI. Low for precision, high for large movements.
`0x5DA8` | `SCRL_SW` |Switch scroll divider. Larger value equals smaller scroll motion
`0x5DA9` | `ROT_R15` |Rotate sensor coordinate by 15 degrees clockwise
`0x5DAA` | `ROT_L15` |Rotate sensor coordinate by 15 degrees counterclockwise
`0x5DAB` | `SCRL_MO` |Enable scroll mode while being pressed
`0x5DAC` | `SCRL_TO` |Toggle scroll mode. Once pushed, mouse mode and scroll mode are switched.
`0x5DAD` | `SCRL_IN` |Invert scroll direction
# VIA Support
* [aki27 provides VIA JSON files](https://github.com/aki27kbd/cocot46plus/tree/main/firmware)
### Gallery
![cocot46plus_photo12](https://i.imgur.com/hPOB98H.jpeg)
![cocot46plus_photo14](https://i.imgur.com/HrtI9w1.jpeg)
![cocot46plus_photo05](https://i.imgur.com/LOcxHIV.jpeg)
![cocot46plus_photo02](https://i.imgur.com/b5O9tKq.jpeg)
![cocot46plus_photo10](https://i.imgur.com/gDx5e64.jpeg)

View File

@ -0,0 +1,3 @@
SRC += matrix.c
CUSTOM_MATRIX = lite
POINTING_DEVICE_DRIVER = adns5050

View File

@ -1,5 +1,6 @@
"""This script automates the copying of the default keymap into your own keymap.
"""
import re
import shutil
from milc import cli
@ -13,6 +14,13 @@ from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.userspace import UserspaceDefs
def validate_keymap_name(name):
"""Returns True if the given keymap name contains only a-z, 0-9 and underscore characters.
"""
regex = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9_]+$')
return bool(regex.match(name))
def prompt_keyboard():
prompt = """{fg_yellow}Select Keyboard{style_reset_all}
If you`re unsure you can view a full list of supported keyboards with {fg_yellow}qmk list-keyboards{style_reset_all}.
@ -60,6 +68,10 @@ def new_keymap(cli):
cli.log.error(f'Default keymap {{fg_cyan}}{keymap_path_default}{{fg_reset}} does not exist!')
return False
if not validate_keymap_name(user_name):
cli.log.error('Keymap names must contain only {fg_cyan}a-z{fg_reset}, {fg_cyan}0-9{fg_reset} and {fg_cyan}_{fg_reset}! Please choose a different name.')
return False
if keymap_path_new.exists():
cli.log.error(f'Keymap {{fg_cyan}}{user_name}{{fg_reset}} already exists! Please choose a different name.')
return False

View File

@ -29,6 +29,7 @@ def _convert_macros(via_macros):
if len(via_macros) == 0:
return list()
split_regex = re.compile(r'(}\,)|(\,{)')
macro_group_regex = re.compile(r'({.+?})')
macros = list()
for via_macro in via_macros:
# Split VIA macro to its elements
@ -38,13 +39,28 @@ def _convert_macros(via_macros):
macro_data = list()
for m in macro:
if '{' in m or '}' in m:
# Found keycode(s)
keycodes = m.split(',')
# Remove whitespaces and curly braces from around keycodes
keycodes = list(map(lambda s: s.strip(' {}'), keycodes))
# Remove the KC prefix
keycodes = list(map(lambda s: s.replace('KC_', ''), keycodes))
macro_data.append({"action": "tap", "keycodes": keycodes})
# Split macro groups
macro_groups = macro_group_regex.findall(m)
for macro_group in macro_groups:
# Remove whitespaces and curly braces from around group
macro_group = macro_group.strip(' {}')
macro_action = 'tap'
macro_keycodes = []
if macro_group[0] == '+':
macro_action = 'down'
macro_keycodes.append(macro_group[1:])
elif macro_group[0] == '-':
macro_action = 'up'
macro_keycodes.append(macro_group[1:])
else:
macro_keycodes.extend(macro_group.split(',') if ',' in macro_group else [macro_group])
# Remove the KC prefixes
macro_keycodes = list(map(lambda s: s.replace('KC_', ''), macro_keycodes))
macro_data.append({"action": macro_action, "keycodes": macro_keycodes})
else:
# Found text
macro_data.append(m)
@ -54,13 +70,13 @@ def _convert_macros(via_macros):
def _fix_macro_keys(keymap_data):
macro_no = re.compile(r'MACRO0?([0-9]{1,2})')
macro_no = re.compile(r'MACRO0?\(([0-9]{1,2})\)')
for i in range(0, len(keymap_data)):
for j in range(0, len(keymap_data[i])):
kc = keymap_data[i][j]
m = macro_no.match(kc)
if m:
keymap_data[i][j] = f'MACRO_{m.group(1)}'
keymap_data[i][j] = f'MC_{m.group(1)}'
return keymap_data