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

[Keyboard] frobiac custom boards and layout #19883

Merged
merged 6 commits into from
Mar 10, 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
32 changes: 32 additions & 0 deletions keyboards/frobiac/blackbowl/blackbowl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2023 @frobiac
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "quantum.h"
#include <stdint.h>
#include <stdbool.h>
#include "i2c_master.h"
#include "wait.h"

extern uint8_t expander_status;
extern uint8_t expander_input_pin_mask;
extern bool i2c_initialized;

void init_blackbowl(void);
void init_expander(void);

// clang-format off
#define I2C_TIMEOUT 100
#define IODIRA 0x00 // i/o direction register
#define IODIRB 0x01
#define GPPUA 0x0C // GPIO pull-up resistor register
#define GPPUB 0x0D
#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
#define GPIOB 0x13
#define OLATA 0x14 // output latch register
#define OLATB 0x15

#define xxx KC_NO

// clang-format on
56 changes: 56 additions & 0 deletions keyboards/frobiac/blackbowl/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2012 Jun Wako <[email protected]>
// Copyright 2013 Oleg Kostyuk <[email protected]>
// Copyright 2017 Erin Call <[email protected]>
// Copyright 2023 @frobiac
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#define MATRIX_ROWS 10
#define MATRIX_COLS 4
#define EXPANDER_COL_REGISTER GPIOA
#define EXPANDER_ROW_REGISTER GPIOB

#ifdef PS2_MOUSE_ENABLE
# define PS2_MOUSE_USE_REMOTE_MODE
# define PS2_MOUSE_INIT_DELAY 1000
#endif

// clang-format off
#ifdef PS2_DRIVER_USART

# define PS2_CLOCK_PIN D5
# define PS2_DATA_PIN D2

/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
/* set DDR of CLOCK as input to be slave */
#define PS2_USART_INIT() do { \
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
UCSR1C = ((1 << UMSEL10) | \
(3 << UPM10) | \
(0 << USBS1) | \
(3 << UCSZ10) | \
(0 << UCPOL1)); \
UCSR1A = 0; \
UBRR1H = 0; \
UBRR1L = 0; \
} while (0)
#define PS2_USART_RX_INT_ON() do { \
UCSR1B = ((1 << RXCIE1) | \
(1 << RXEN1)); \
} while (0)
#define PS2_USART_RX_POLL_ON() do { \
UCSR1B = (1 << RXEN1); \
} while (0)
#define PS2_USART_OFF() do { \
UCSR1C = 0; \
UCSR1B &= ~((1 << RXEN1) | \
(1 << TXEN1)); \
} while (0)
#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1))
#define PS2_USART_RX_DATA UDR1
#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
#define PS2_USART_RX_VECT USART1_RX_vect
#endif

85 changes: 85 additions & 0 deletions keyboards/frobiac/blackbowl/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"manufacturer": "frobiac",
"keyboard_name": "blackbowl",
"url": "https://www.github.com/frobiac/adnw",
"maintainer": "frobiac",
"bootloader": "halfkay",
"processor": "atmega32u4",
"diode_direction": "ROW2COL",
"features": {
"audio": false,
"backlight": false,
"bootmagic": false,
"command": false,
"console": false,
"dynamic_macro": true,
"extrakey": true,
"mousekey": true,
"nkro": false,
"unicode": false,
"rgblight": false
},
"build": {
"lto": true
},
"usb": {
"device_version": "1.0.0",
"pid": "0x1D50",
"vid": "0x6033"
},
"matrix_pins": {
"cols": [ null, null, null, null ],
"rows": [ null, null, null, null, null, null, null, null, null, null ]
},
"layouts": {
"LAYOUT": {
"layout": [
{"matrix": [5, 3], "label":"K", "x":0, "y":1.00},
{"matrix": [6, 3], "label":"U", "x":1, "y":0.50},
{"matrix": [7, 3], "label":"Q", "x":2, "y":0.00},
{"matrix": [8, 3], "label":".", "x":3, "y":0.00},
{"matrix": [9, 3], "label":"J", "x":4, "y":0.00},

{"matrix": [0, 3], "label":"P", "x":6, "y":0.00},
{"matrix": [1, 3], "label":"C", "x":7, "y":0.00},
{"matrix": [2, 3], "label":"L", "x":8, "y":0.00},
{"matrix": [3, 3], "label":"M", "x":9, "y":0.50},
{"matrix": [4, 3], "label":"F", "x":10, "y":1.00},

{"matrix": [5, 2], "label":"H", "x":0, "y":2.00},
{"matrix": [6, 2], "label":"I", "x":1, "y":1.50},
{"matrix": [7, 2], "label":"E", "x":2, "y":1.00},
{"matrix": [8, 2], "label":"A", "x":3, "y":1.00},
{"matrix": [9, 2], "label":"O", "x":4, "y":1.00},

{"matrix": [0, 2], "label":"D", "x":6, "y":1.00},
{"matrix": [1, 2], "label":"T", "x":7, "y":1.00},
{"matrix": [2, 2], "label":"R", "x":8, "y":1.00},
{"matrix": [3, 2], "label":"N", "x":9, "y":1.50},
{"matrix": [4, 2], "label":"S", "x":10, "y":2.00},

{"matrix": [5, 1], "label":"X", "x":0, "y":3.00},
{"matrix": [6, 1], "label":"Y", "x":1, "y":2.50},
{"matrix": [7, 1], "label":"-", "x":2, "y":2.00},
{"matrix": [8, 1], "label":",", "x":3, "y":2.00},
{"matrix": [9, 1], "label":"/", "x":4, "y":2.00},

{"matrix": [0, 1], "label":"B", "x":6, "y":2.00},
{"matrix": [1, 1], "label":"G", "x":7, "y":2.00},
{"matrix": [2, 1], "label":"W", "x":8, "y":2.00},
{"matrix": [3, 1], "label":"V", "x":9, "y":2.50},
{"matrix": [4, 1], "label":"Z", "x":10, "y":3.00},

{"matrix": [5, 0], "label":" ", "x":0, "y":0.00},
{"matrix": [7, 0], "label":"Gui", "x":2, "y":3.00},
{"matrix": [8, 0], "label":"tab", "x":3, "y":3.00},
{"matrix": [9, 0], "label":"spc", "x":4, "y":3.00},

{"matrix": [0, 0], "label":"L2", "x":6, "y":3.00},
{"matrix": [1, 0], "label":"Sh", "x":7, "y":3.00},
{"matrix": [2, 0], "label":"L3", "x":8, "y":3.00},
{"matrix": [4, 0], "label":"Fx", "x":10, "y":0.00}
]
}
}
}
85 changes: 85 additions & 0 deletions keyboards/frobiac/blackbowl/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2023 @frobiac
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H

#include "keymap_german.h"

enum layer_number {
_ADNW = 0,
_QWERTZ,
_NAVNUM,
_SYMBOL,
_FUNC,
_MOUSE,
};

#define CTL_TAB LCTL_T(KC_TAB)
#define ALT_SPC LALT_T(KC_SPC)
#define NAV_ESC LT(_NAVNUM, KC_ESC)
#define SFT_BSP LSFT_T(KC_BSPC)
#define SYM_ENT LT(_SYMBOL, KC_ENT)
#define MOUSE_X LT(_MOUSE, KC_X)
#define MOUSE_Y LT(_MOUSE, KC_Y)

/*
* ┌───┐ ┌───┬───┬───┐ ┌───┬───┬───┐ ┌───┐
* │MOU├───┤ Q │ . │ J │ │ P │ C │ L ├───┤Fx │
* ├───┤ U ├───┼───┼───┤ ├─[TP]──┼───┤ M ├───┤
* │ K ├───┤ E │ A │ O │ │ D │ T │ R ├───R F │
* ├───┤ I ├───┼───┼───┤ ├───┼───┼───┤ N ├───┤
* │ H ├───┤ - │ ; │ / │ │ D │ G │ W ├───┤ S │
* ├───┤ Y ├───┼───┼───┤ ├───┼───┼───┤ V ├───┤
* │ X ├───┤ │Tab│Spc│ │Esc│Bsp│Ret├───┤ Z │
* └───┘ └───┴───┴───┘ └───┴───┴───┘ └───┘
*
*/

// clang-format off

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADNW] = LAYOUT(
KC_K, KC_U, KC_Q, KC_DOT, KC_J, KC_P, KC_C, KC_L, KC_M, KC_F,
KC_H, KC_I, KC_E, KC_A, KC_O, KC_D, KC_T, KC_R, KC_N, KC_S,
MOUSE_X, DE_Y, DE_MINS, KC_COMM, DE_SLSH, KC_B, KC_G, KC_W, KC_V, RSFT_T(DE_Z),
XXXXXXX, KC_LGUI, CTL_TAB, ALT_SPC, NAV_ESC, SFT_BSP, SYM_ENT, MO(_FUNC)
),

[_QWERTZ] = LAYOUT(
KC_Q, KC_W, KC_E, KC_R, KC_T, DE_Z, 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,
MOUSE_Y, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SLSH),
XXXXXXX, KC_LGUI, CTL_TAB, ALT_SPC, NAV_ESC, SFT_BSP, SYM_ENT, MO(_FUNC)
),

[_SYMBOL] = LAYOUT(
DE_AT, DE_DEG, DE_LBRC, DE_RBRC, DE_HASH, DE_EXLM, DE_LABK, DE_RABK, DE_EQL, DE_AMPR,
DE_BSLS, DE_EURO, DE_LCBR, DE_RCBR, DE_ASTR, DE_QUES, DE_LPRN, DE_RPRN, DE_PLUS, KC_ENT,
XXXXXXX, DE_DLR, DE_PIPE, DE_TILD, DE_GRV, DE_CIRC, DE_PERC, DE_DQUO, DE_QUOT, XXXXXXX,
_______, _______, _______, _______, _______, _______, _______, _______
),

[_NAVNUM] = LAYOUT(
KC_PGUP, KC_BSPC, KC_UP, KC_DEL, KC_PGDN, DE_SS, KC_7, KC_8, KC_9, DE_ADIA,
KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END, KC_DOT, KC_4, KC_5, KC_6, DE_ODIA,
XXXXXXX, XXXXXXX, KC_INS, XXXXXXX, XXXXXXX, KC_0, KC_1, KC_2, KC_3, DE_UDIA,
_______, _______, _______, _______, _______, _______, _______, _______
),

[_FUNC] = LAYOUT(
XXXXXXX, XXXXXXX, XXXXXXX, DF(_QWERTZ),DF(_ADNW), XXXXXXX, KC_F7, KC_F8, KC_F9, KC_F10,
DM_REC1, DM_RSTP, DM_PLY1, XXXXXXX, QK_RBT, XXXXXXX, KC_F4, KC_F5, KC_F6, KC_F11,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, QK_BOOT, XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F12,
_______, _______, _______, _______, _______, _______, _______, _______
),

[_MOUSE] = LAYOUT(
KC_WH_L, XXXXXXX, KC_MS_U, XXXXXXX, XXXXXXX, KC_ACL0, XXXXXXX, KC_BTN3, XXXXXXX, KC_BTN5,
KC_WH_R, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_U, KC_ACL1, XXXXXXX, KC_BTN1, KC_BTN2, KC_BTN4,
MOUSE_X, KC_BTN1, KC_BTN3, KC_BTN2, KC_WH_D, KC_ACL2, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
_______, _______, _______, _______, _______, _______, _______, _______
),

};

// clang-format on
115 changes: 115 additions & 0 deletions keyboards/frobiac/blackbowl/matrix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2013 Oleg Kostyuk <[email protected]>
// Copyright 2017 Erin Call <[email protected]>
// Copyright 2023 @frobiac
// SPDX-License-Identifier: GPL-2.0-or-later

// This implements a matrix scan (lite) for the BlackBowl keyboard.
// Each side has a dedicated MCP23018 I2C expander.

#include <stdint.h>
frobiac marked this conversation as resolved.
Show resolved Hide resolved
#include <stdbool.h>
#include <avr/io.h>
#include "wait.h"
#include "action_layer.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "blackbowl.h"
#include "i2c_master.h"
#include "timer.h"

#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
#define ROW_SHIFTER ((matrix_row_t)1)

static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);

static uint8_t expander_reset_loop;
uint8_t expander_status;
const uint8_t expander_input_mask = ((1 << MATRIX_ROWS_PER_SIDE) - 1); // No special mapping, 5 bits [0..4] per side
bool i2c_initialized = false;

static const uint8_t I2C_ADDR_RIGHT = 0x4E;
static const uint8_t I2C_ADDR_LEFT = 0x46;
static const uint8_t i2c_addr[] = {I2C_ADDR_RIGHT, I2C_ADDR_LEFT};

void matrix_init_custom(void) {
if (!i2c_initialized) {
i2c_init();
wait_ms(1000);
}

// Pin direction and pull-up depends on diode direction and column register:
// ROW2COL, GPIOA => input, output
uint8_t direction[2] = {0, expander_input_mask};
uint8_t pullup[2] = {0, expander_input_mask};

for (uint8_t i = 0; i < 2; ++i) {
expander_status = i2c_writeReg(i2c_addr[i], IODIRA, direction, 2, I2C_TIMEOUT);
if (expander_status) return;

expander_status = i2c_writeReg(i2c_addr[i], GPPUA, pullup, 2, I2C_TIMEOUT);
}
}

bool matrix_scan_custom(matrix_row_t current_matrix[]) {
bool matrix_has_changed = false;

if (expander_status) { // if there was an error
++expander_reset_loop;
if (++expander_reset_loop == 0) {
// since expander_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
// this will be approx bit more frequent than once per second
matrix_init_custom();
}
}

for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
matrix_has_changed |= read_rows_on_col(current_matrix, current_col);
}

return matrix_has_changed;
}

static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
bool matrix_changed = false;
uint8_t port = 0xFF & ~(1 << current_col);
uint8_t column_state[] = {0, 0};

// On both expanders: select col and read rows
for (size_t i = 0; i < 2; ++i) {
if (!expander_status) {
expander_status = i2c_writeReg(i2c_addr[i], EXPANDER_COL_REGISTER, &port, 1, I2C_TIMEOUT);
}
wait_us(30);

if (expander_status) {
return false;
}

expander_status = i2c_readReg(i2c_addr[i], EXPANDER_ROW_REGISTER, &column_state[i], 1, I2C_TIMEOUT);
column_state[i] = (~column_state[i]) & ((1 << MATRIX_ROWS_PER_SIDE) - 1);
}

// now map rows 0..4 on each side to cumulative to 0..9
uint16_t col_state = column_state[0] | ((column_state[1] << MATRIX_ROWS_PER_SIDE) /*& 0x3e0*/);

for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[current_row];

if (col_state & (1 << current_row)) {
// key closed; set state bit in matrix
current_matrix[current_row] |= (ROW_SHIFTER << current_col);
} else {
// key open; clear state bit in matrix
current_matrix[current_row] &= ~(ROW_SHIFTER << current_col);
}

// Determine whether the matrix changed state
if ((last_row_value != current_matrix[current_row]) && !(matrix_changed)) {
matrix_changed = true;
}
}
return matrix_changed;
}
Loading