Skip to content

Commit

Permalink
QMK firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
rschenk committed Jun 26, 2024
1 parent 383c99b commit c427d1c
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 3 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,21 @@ Be advised that right now the underglow only works on the XIAO nRF52840 board, a
| Board | Chip | USB Wired | Bluetooth Wireless | RGB Underglow | Comments |
| --------------------- | -------- | ------------------ | ------------------ | ------------------ | ------------------------------------------------------------ |
| XIAO | SAMD21 | :white_check_mark: | :x: | :x: | Should work but untested |
| Adafruit Qt PY | SAMD21 | :white_check_mark: | :x: | :x: | Should work but untested |
| XIAO BLE | nRF52840 | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
| XIAO RP2040 | RP2040 | :white_check_mark: | :x: | :x: for now | Underglow [maybe someday](https://github.com/zmkfirmware/zmk/issues/1085) |
| Adafruit Qt PY RP2040 | RP2040 | :white_check_mark: | :x: | :x: for now | Should work but untested |

### QMK

I have not written QMK firmware yet, but maybe I will for the RP2040.
Copy the contents of `firmware/qmk/keyboards/re_gret` into `[your_qmk_firmware]/keyboards/re_gret`, since I have not put the Re-gret firmware into the official QMK repo.

Only the XIAO RP2040 is supported. The Adafruit QT Py RP2040 might possibly work but I don't think the reset button will function.

| Board | Chip | USB Wired | RGB Underglow | Comments |
| --------------------- | -------- | ------------------ | ------------------ | ------------------------------------------------------------ |
| XIAO RP2040 | RP2040 | :white_check_mark: | :white_check_mark: | |

## Related

* I cribbed the Xiao footprint, pogo pin idea, and battery from the [revxlp](https://gitlab.com/lpgalaxy/revxlp)
* I based the QMK shift register matrix code on [Sadek's](https://github.com/sadekbaroudi/qmk_firmware)
* My original 36 key [Egret](https://github.com/rschenk/egret) was the starting point
31 changes: 31 additions & 0 deletions firmware/qmk/keyboards/re_gret/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 Ryan Schenk (@rschenk)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#define MATRIX_COLS 5
#define MATRIX_ROWS 8

#define SPI_SCK_PIN GP2
#define SPI_MOSI_PIN GP3
#define SPI_MISO_PIN NO_PIN

#define SHIFTREG_MATRIX_ROW_CS GP4
#define SHIFTREG_DIVISOR 8
#define SHIFTREG_COLS 5
#define SHIFTREG_ROWS 8

#define MATRIX_COL_PINS { GP27, GP28, GP29, GP6, GP7 }
// Row Number 0 1 2 3 4 5 6 7
// SHR Pin Q: H G F E A B C D
#define SHIFTREG_ROW_PINS { 0x80, 0x40, 0x20, 0x10, 0x01, 0x02, 0x04, 0x08 }

#define WS2812_DI_PIN GP26
#define RGBLIGHT_LED_COUNT 11

#ifdef RGBLIGHT_ENABLE
#define RGBLIGHT_EFFECT_RAINBOW_SWIRL // enable rainbow swirl
#define RGBLIGHT_SLEEP // turn off LEDs when host sleeps
#define RGBLIGHT_LAYERS // per-layer LED effects
#define RGBLIGHT_DEFAULT_MODE RGBLIGHT_MODE_RAINBOW_SWIRL
#endif
10 changes: 10 additions & 0 deletions firmware/qmk/keyboards/re_gret/halconf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2024 Ryan Schenk (@rschenk)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#define HAL_USE_SPI TRUE
#define SPI_USE_WAIT TRUE
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD

#include_next <halconf.h>
63 changes: 63 additions & 0 deletions firmware/qmk/keyboards/re_gret/keyboard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"manufacturer": "Ryan Schenk",
"keyboard_name": "re_gret",
"maintainer": "rschenk",
"bootloader": "rp2040",
"diode_direction": "ROW2COL",
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"processor": "RP2040",
"url": "https://github.com/rschenk/re-gret",
"usb": {
"device_version": "1.0.0",
"pid": "0xE9E8",
"vid": "0xFEED"
},
"community_layouts": ["split_3x5_2"],
"layouts": {
"LAYOUT_split_3x5_2": {
"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, 3], "x": 3.5, "y": 3.25},
{"matrix": [3, 4], "x": 4.5, "y": 3.5},
{"matrix": [7, 4], "x": 6.5, "y": 3.5},
{"matrix": [7, 3], "x": 7.5, "y": 3.25}
]
}
}
}
26 changes: 26 additions & 0 deletions firmware/qmk/keyboards/re_gret/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* ┌───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┐
* │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │
* ├───┼───┼───┼───┼───┤ ├───┼───┼───┼───┼───┤
* │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ ; │
* ├───┼───┼───┼───┼───┤ ├───┼───┼───┼───┼───┤
* │ Z │ X │ C │ V │ B │ │ N │ M │ , │ . │ / │
* └───┴───┴───┴───┴───┘ └───┴───┴───┴───┴───┘
* ┌───┐ ┌───┐
* │Bsp├───┐ ┌───┤Ent│
* └───┤Tab│ │Spc├───┘
* └───┘ └───┘
*/
[0] = LAYOUT_split_3x5_2(
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,
KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
KC_BSPC, KC_TAB, KC_SPC, KC_ENT
)
};
153 changes: 153 additions & 0 deletions firmware/qmk/keyboards/re_gret/matrix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright 2024 Ryan Schenk (@rschenk)
// Copyright 2022 @sadekbaroudi (Sadek Baroudi)
// SPDX-License-Identifier: GPL-3.0-or-later
#include "quantum.h"
#include "spi_master.h"
#include <string.h> /* memset */
#include <unistd.h> /* close */
#include "quantum.h"
#include "matrix.h"
#ifdef FP_SR595_MATRIX_DEBUG
#include <time.h>
#include <stdlib.h>
#define FP_SR595_MATRIX_DEBUG_RATIO 10000
#endif

#if (!defined(SHIFTREG_MATRIX_ROW_CS))
# error Missing shift register I/O pin definitions
#endif

int matrixArraySize = MATRIX_ROWS * sizeof(matrix_row_t);
matrix_row_t oldMatrix[MATRIX_ROWS];

#define SHIFTREG_OUTPUT_BITS 8
pin_t colPinsSR[MATRIX_COLS] = MATRIX_COL_PINS;
uint8_t rowPinCodesSR[SHIFTREG_ROWS] = SHIFTREG_ROW_PINS;

// semaphore to make sure SPI doesn't get called multiple times
static bool shiftRegisterSPILocked = false;

void semaphore_lock(bool value) {
shiftRegisterSPILocked = value;
}

bool semaphore_is_locked(void) {
return shiftRegisterSPILocked;
}

void sr_74hc595_spi_stop(void) {
spi_stop();
semaphore_lock(false);
}

bool sr_74hc595_spi_start(void) {
if (!spi_start(SHIFTREG_MATRIX_ROW_CS, false, 0, SHIFTREG_DIVISOR)) {
dprintf("74hc595 matrix: failed to start spi\n");
sr_74hc595_spi_stop();
return false;
}

semaphore_lock(true);
wait_us(1); // not sure if I need this
return true;
}

bool sr_74hc595_spi_send_byte(uint8_t data) {
sr_74hc595_spi_start();
gpio_write_pin_low(SHIFTREG_MATRIX_ROW_CS);
matrix_io_delay();
spi_write(data);
matrix_io_delay();
gpio_write_pin_high(SHIFTREG_MATRIX_ROW_CS);
sr_74hc595_spi_stop();
return true;
}

/**
* Set the entire shift register to be full of inactive bits
*/
void clearRows(void) {
uint8_t value = 0b00000000;
sr_74hc595_spi_send_byte(value);
}

void setRow(int rowNumber, bool test_run) {
uint8_t rowShiftByte = rowPinCodesSR[rowNumber];
if(test_run) {
dprintf("byte sent: %d\n", rowShiftByte);
}
sr_74hc595_spi_send_byte(rowShiftByte);
}

/*
* Override QMK matrix initialization
*/
void matrix_init_custom(void) {
wait_ms(300);
spi_init();

// Set up initial states for all the column pins
for(int c = 0; c < SHIFTREG_COLS; c++) {
// Note: This needs to use the internal pull down resistors, and atmegas
// do *not* support that
gpio_set_pin_input_low(colPinsSR[c]);
}

// Set the CS to low by default, and specify as an output pin
gpio_write_pin_high(SHIFTREG_MATRIX_ROW_CS); // should be high when using SPI?
gpio_set_pin_output(SHIFTREG_MATRIX_ROW_CS);

// Since it's the init, deactivate all the columns. We'll activate once we
// get to the matrix scan
clearRows();
}

/*
* Override QMK matrix scan
*/
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
// respect the semaphore
if (semaphore_is_locked()) {
return false;
}

bool matrix_has_changed = false;

// reset the current matrix, as we'll be updating and comparing to the old matrix
memset(current_matrix, 0, matrixArraySize);

#ifdef FP_SR595_MATRIX_DEBUG
bool debug_output = ((rand() % FP_SR595_MATRIX_DEBUG_RATIO) == 1);
#else
bool debug_output = false;
#endif

// Loop through the rows, activating one at a time, and read the columns,
// and place in the new current_matrix
for (int r = 0; r < SHIFTREG_ROWS; r++) {
if (debug_output) {
dprintf("row iteration: %d\n", r);
}
setRow(r, debug_output);
matrix_io_delay();

for (int c = 0; c < SHIFTREG_COLS; c++) {
current_matrix[r] |= ((gpio_read_pin(colPinsSR[c]) ? 1 : 0) << c);
}
}

matrix_has_changed = memcmp(current_matrix, oldMatrix, matrixArraySize) != 0;
memcpy(oldMatrix, current_matrix, matrixArraySize);

#ifdef FP_SR595_MATRIX_DEBUG
if (matrix_has_changed) {
matrix_print();
}
#endif

// Deactivate all the columns for the next run.
clearRows();
matrix_io_delay();

return matrix_has_changed;
}
9 changes: 9 additions & 0 deletions firmware/qmk/keyboards/re_gret/mcuconf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2024 Ryan Schenk (@rschenk)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include_next <mcuconf.h>

#undef RP_SPI_USE_SPI0
#define RP_SPI_USE_SPI0 TRUE
27 changes: 27 additions & 0 deletions firmware/qmk/keyboards/re_gret/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Re-gret

![re_gret](https://github.com/rschenk/re-gret/blob/main/images/IMG_0812.jpeg?raw=true)

A 34-key keyboard powered by a Seeed XIAO RP2040, with hot-swappable ChocV1 switches.

* Keyboard Maintainer: [Ryan Schenk](https://github.com/rschenk)
* Hardware Supported: Re-gret PCB with Seeed XIAO RP2040 controller
* Hardware Availability: Gerbers are available in the [Re-gret repo](https://github.com/rschenk/re-gret) and the controller is available from [Seeed Studio](https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html)

Make example for this keyboard (after setting up your build environment):

make re_gret:default

Flashing example for this keyboard:

make re_gret:default:flash

See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

## Bootloader

Enter the bootloader in 3 ways:

* **Bootmagic reset**: Hold down the top-left key ("Q" on qwerty) and plug in the keyboard
* **Physical reset button**: Double click the reset button
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
6 changes: 6 additions & 0 deletions firmware/qmk/keyboards/re_gret/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SRC += matrix.c

SPI_DRIVER_REQUIRED = yes
CUSTOM_MATRIX = lite
RGBLIGHT_ENABLE = yes
WS2812_DRIVER = vendor

0 comments on commit c427d1c

Please sign in to comment.