Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Adding Bad Wings Support #20153

Merged
merged 20 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions keyboards/hazel/bad_wings/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2023 Jason Hazel (@jasonhazel)
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#define SPI_SCK_PIN GP2
#define SPI_MOSI_PIN GP3
#define SPI_MISO_PIN GP4

#define SHIFTREG_MATRIX_COL_CS GP0
#define SHIFTREG_DIVISOR 8
#define SHIFTREG_ROWS 5
#define SHIFTREG_COLS 8

#define MATRIX_ROW_PINS_SR { GP26, GP27, GP28, GP29, GP6 }

#define POINTING_DEVICE_CS_PIN GP1
#define CIRQUE_PINNACLE_DIAMETER_MM 35
#define POINTING_DEVICE_ROTATION_90
12 changes: 12 additions & 0 deletions keyboards/hazel/bad_wings/halconf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2023 Jason Hazel (@jasonhazel)
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#define HAL_USE_SPI TRUE
#define HAL_USE_I2C TRUE
#define HAL_USE_PWM TRUE
#define SPI_USE_WAIT TRUE
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD

#include_next <halconf.h>
66 changes: 66 additions & 0 deletions keyboards/hazel/bad_wings/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"keyboard_name": "Bad Wings",
"manufacturer": "Hazel",
"maintainer": "jasonhazel",
"url": "https://shop.hazel.cc/products/bad-wings",
"usb": {
"vid": "0x4A48",
"pid": "0x4257",
"device_version": "1.0.0"
},
"processor": "RP2040",
"bootloader": "rp2040",
"matrix_size": {
"cols": 8,
"rows": 5
},
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"deferred_exec": true,
"nkro": false
},
"community_layouts": [ "split_3x5_3" ],
"layouts": {
"LAYOUT_split_3x5_3": {
"layout": [
{ "label": "K00", "matrix": [0, 0], "w": 1, "x": 0, "y": 0.75 },
{ "label": "K10", "matrix": [1, 0], "w": 1, "x": 1, "y": 0.5 },
{ "label": "K20", "matrix": [2, 0], "w": 1, "x": 2, "y": 0 },
{ "label": "K30", "matrix": [3, 0], "w": 1, "x": 3, "y": 0.25 },
{ "label": "K40", "matrix": [4, 0], "w": 1, "x": 4, "y": 0.36 },
{ "label": "K44", "matrix": [4, 4], "w": 1, "x": 8, "y": 0.36 },
{ "label": "K34", "matrix": [3, 4], "w": 1, "x": 9, "y": 0.25 },
{ "label": "K24", "matrix": [2, 4], "w": 1, "x": 10, "y": 0 },
{ "label": "K14", "matrix": [1, 4], "w": 1, "x": 11, "y": 0.5 },
{ "label": "K04", "matrix": [0, 4], "w": 1, "x": 12, "y": 0.75 },
{ "label": "K01", "matrix": [0, 1], "w": 1, "x": 0, "y": 1.75 },
{ "label": "K11", "matrix": [1, 1], "w": 1, "x": 1, "y": 1.5 },
{ "label": "K21", "matrix": [2, 1], "w": 1, "x": 2, "y": 1 },
{ "label": "K31", "matrix": [3, 1], "w": 1, "x": 3, "y": 1.25 },
{ "label": "K41", "matrix": [4, 1], "w": 1, "x": 4, "y": 1.36 },
{ "label": "K45", "matrix": [4, 5], "w": 1, "x": 8, "y": 1.36 },
{ "label": "K35", "matrix": [3, 5], "w": 1, "x": 9, "y": 1.25 },
{ "label": "K25", "matrix": [2, 5], "w": 1, "x": 10, "y": 1 },
{ "label": "K15", "matrix": [1, 5], "w": 1, "x": 11, "y": 1.5 },
{ "label": "K05", "matrix": [0, 5], "w": 1, "x": 12, "y": 1.75 },
{ "label": "K02", "matrix": [0, 2], "w": 1, "x": 0, "y": 2.75 },
{ "label": "K12", "matrix": [1, 2], "w": 1, "x": 1, "y": 2.5 },
{ "label": "K22", "matrix": [2, 2], "w": 1, "x": 2, "y": 2 },
{ "label": "K32", "matrix": [3, 2], "w": 1, "x": 3, "y": 2.25 },
{ "label": "K42", "matrix": [4, 2], "w": 1, "x": 4, "y": 2.36 },
{ "label": "K46", "matrix": [4, 6], "w": 1, "x": 8, "y": 2.36 },
{ "label": "K36", "matrix": [3, 6], "w": 1, "x": 9, "y": 2.25 },
{ "label": "K26", "matrix": [2, 6], "w": 1, "x": 10, "y": 2 },
{ "label": "K16", "matrix": [1, 6], "w": 1, "x": 11, "y": 2.5 },
{ "label": "K06", "matrix": [0, 6], "w": 1, "x": 12, "y": 2.75 },
{ "label": "K23", "matrix": [2, 3], "w": 1, "x": 3, "y": 3.25 },
{ "label": "K33", "matrix": [3, 3], "w": 1, "x": 4, "y": 3.36 },
{ "label": "K43", "matrix": [4, 3], "w": 1, "x": 5, "y": 3.47 },
{ "label": "K47", "matrix": [4, 7], "w": 1, "x": 7, "y": 3.47 },
{ "label": "K37", "matrix": [3, 7], "w": 1, "x": 8, "y": 3.36 },
{ "label": "K27", "matrix": [2, 7], "w": 1, "x": 9, "y": 3.25 }
]
}
}
}
16 changes: 16 additions & 0 deletions keyboards/hazel/bad_wings/keymaps/default/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2023 Jason Hazel (@jasonhazel)
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#define TAPPING_TERM 200
#define PERMISSIVE_HOLD
#define IGNORE_MOD_TAP_INTERRUPT
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM_PER_KEY
#define ONESHOT_TAP_TOGGLE 10
#define ONESHOT_TIMEOUT 500
#define DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD
#define CIRQUE_PINNACLE_TAP_ENABLE
#define CIRQUE_PINNACLE_POSITION_MODE CIRQUE_PINNACLE_ABSOLUTE_MODE
#define CIRQUE_DEVICE_GESTURES_SCROLL_ENABLE
35 changes: 35 additions & 0 deletions keyboards/hazel/bad_wings/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2023 Jason Hazel (@jasonhazel)
// SPDX-License-Identifier: GPL-3.0-or-later

#include QMK_KEYBOARD_H

layer_state_t layer_state_set_user(layer_state_t state) {
return update_tri_layer_state(state, 1, 2, 3);
}

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_split_3x5_3(
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_QUOT, \
KC_Z, LGUI_T(KC_X), LALT_T(KC_C), KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, \
KC_LCTL, OSL(1), OSM(MOD_LSFT), KC_SPC, LT(2, KC_BSPC), KC_ENT
),
[1] = LAYOUT_split_3x5_3(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_RBRC, KC_RCBR, KC_RPRN, KC_RABK, KC_NO, \
KC_GRV, KC_TILD, KC_UNDS, KC_EQL, KC_NO, KC_LBRC, KC_LCBR, KC_LPRN, KC_LABK, KC_BACKSLASH, \
KC_NO, KC_NO, KC_PLUS, KC_MINS, KC_NO, KC_NO, KC_NO, KC_COLN, KC_DOT, KC_SCLN, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
),
[2] = LAYOUT_split_3x5_3(
KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_PIPE, KC_NO, \
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, \
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_DOT, KC_NO, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
),
[3] = LAYOUT_split_3x5_3(
KC_ESC, KC_F1, KC_F4, KC_F7, KC_F10, KC_NO, KC_HOME, KC_UP, KC_END, KC_BSPC, \
KC_TAB, KC_F2, KC_F5, KC_F8, KC_F11, KC_NO, KC_LEFT, KC_DOWN, KC_RIGHT, KC_ENT, \
KC_NO, KC_F3, KC_F6, KC_F9, KC_F12, KC_NO, KC_MPRV, KC_MPLY, KC_MNXT, KC_DEL, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
)
};
2 changes: 2 additions & 0 deletions keyboards/hazel/bad_wings/keymaps/default/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MOUSEKEY_ENABLE = yes
EXTRAKEY_ENABLE = yes
137 changes: 137 additions & 0 deletions keyboards/hazel/bad_wings/matrix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright 2022 @sadekbaroudi (Sadek Baroudi)
jasonhazel marked this conversation as resolved.
Show resolved Hide resolved
// Copyright 2023 @jasonhazel (Jason Hazel)
// 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"

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

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

#define SHIFTREG_OUTPUT_BITS 8
pin_t rowPinsSR[SHIFTREG_ROWS] = MATRIX_ROW_PINS_SR;

// 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_COL_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();
writePinLow(SHIFTREG_MATRIX_COL_CS);
matrix_io_delay();
spi_write(data);
matrix_io_delay();
writePinHigh(SHIFTREG_MATRIX_COL_CS);
sr_74hc595_spi_stop();
return true;
}

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

void setColumn(int columnShift, bool test_run) {
uint8_t columnShiftByte = ((uint8_t)1 << columnShift);
if(test_run) {
dprintf("byte sent: %d\n", columnShiftByte);
}
sr_74hc595_spi_send_byte(columnShiftByte);
}

/*
* override of the qmk intialization function
*/
void matrix_init_custom(void) {
wait_ms(300);
spi_init();
// Set up the initial states for all the row pins
for (int r = 0; r < SHIFTREG_ROWS; r++) {
// Note: This needs to use the internal pull down resistors, and atmegas do *not* support that
setPinInputLow(rowPinsSR[r]);
}

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

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

bool matrix_scan_custom(matrix_row_t current_matrix[]) {
// respect the semaphore
if (semaphore_is_locked()) {
return false;
}

// Keep track of if something was modified
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);


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

for (int r = 0; r < SHIFTREG_ROWS; r++) {
current_matrix[r] |= ((readPin(rowPinsSR[r]) ? 1 : 0) << c);
}
}

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

if (matrix_has_changed) {
matrix_print();
}


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

return matrix_has_changed;
}
11 changes: 11 additions & 0 deletions keyboards/hazel/bad_wings/mcuconf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2023 Jason Hazel (@jasonhazel)
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include_next "mcuconf.h"

#undef RP_SPI_USE_SPI0
#define RP_SPI_USE_SPI0 TRUE
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 TRUE
27 changes: 27 additions & 0 deletions keyboards/hazel/bad_wings/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Bad Wings

![Bad Wings](https://i.imgur.com/QpfcEj8h.png)

36 key unibody split

* Keyboard Maintainer: [Jason Hazel](https://github.com/jasonhazel)
* Hardware Supported: Bad Wings v1
* Hardware Availability: [Hazel's Garage](https://shop.hazel.cc/products/bad-wings)

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

make hazel/bad_wings:default

Flashing example for this keyboard:

make hazel/bad_wings: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 and plug in the keyboard
* **Physical reset button**: Hold Xiao B button, press Xiao R button, release B
* **Keycode in layout**: There is no key mapped to `QK_BOOT` in the pre-created keymaps, but you may assign this key in any keymaps you create
10 changes: 10 additions & 0 deletions keyboards/hazel/bad_wings/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
TRI_LAYER_ENABLE = yes
CAPS_WORD_ENABLE = yes

SRC += matrix.c

QUANTUM_LIB_SRC += spi_master.c
CUSTOM_MATRIX = lite

POINTING_DEVICE_DRIVER = cirque_pinnacle_spi
POINTING_DEVICE_ENABLE = yes