[Keyboard] Update ZSA Moonlander (#23911)
This commit is contained in:
parent
48d3edd66f
commit
e9cb9f42a5
7 changed files with 365 additions and 331 deletions
|
@ -18,60 +18,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define WEBUSB_LANDING_PAGE_URL u8"configure.ergodox-ez.com"
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 12
|
||||
#define MATRIX_COLS 7
|
||||
|
||||
/* PCB default pin-out */
|
||||
// #define MATRIX_ROW_PINS { B10, B11, B12, B13, B14, B15 }
|
||||
// #define MATRIX_COL_PINS { A0, A1, A2, A3, A6, A7, B0 }
|
||||
|
||||
// #define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 }
|
||||
// #define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 }
|
||||
|
||||
// #define MCP23_LED_R GPB7
|
||||
// #define MCP23_LED_G GPB6
|
||||
// #define MCP23_LED_B GPA7
|
||||
|
||||
#define EEPROM_I2C_24LC128
|
||||
|
||||
// Not needed, is default address:
|
||||
// #define EXTERNAL_EEPROM_I2C_BASE_ADDRESS 0b10100000
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION ROW2COL
|
||||
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
*/
|
||||
|
||||
/* disable debug print */
|
||||
//#define NO_DEBUG
|
||||
|
||||
/* disable print */
|
||||
//#define NO_PRINT
|
||||
|
||||
/* disable action features */
|
||||
//#define NO_ACTION_LAYER
|
||||
//#define NO_ACTION_TAPPING
|
||||
//#define NO_ACTION_ONESHOT
|
||||
|
||||
#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
|
||||
#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
|
||||
|
||||
#define MOUSEKEY_INTERVAL 20
|
||||
#define MOUSEKEY_DELAY 0
|
||||
#define MOUSEKEY_TIME_TO_MAX 60
|
||||
#define MOUSEKEY_MAX_SPEED 7
|
||||
#define MOUSEKEY_WHEEL_DELAY 400
|
||||
#define MOUSEKEY_WHEEL_INTERVAL MOUSEKEY_INTERVAL
|
||||
#define MOUSEKEY_WHEEL_MAX_SPEED MOUSEKEY_MAX_SPEED
|
||||
#define MOUSEKEY_WHEEL_TIME_TO_MAX MOUSEKEY_TIME_TO_MAX
|
||||
|
||||
#define MUSIC_MAP
|
||||
|
||||
#define FIRMWARE_VERSION_SIZE 17
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"bootmagic": true,
|
||||
"command": true,
|
||||
"console": true,
|
||||
"deferred_exec": true,
|
||||
"extrakey": true,
|
||||
"mousekey": true,
|
||||
"nkro": true,
|
||||
|
@ -37,6 +38,13 @@
|
|||
"eeprom": {
|
||||
"driver": "i2c"
|
||||
},
|
||||
"mousekey": {
|
||||
"delay": 0,
|
||||
"interval": 20,
|
||||
"max_speed": 7,
|
||||
"time_to_max": 60,
|
||||
"wheel_delay": 400
|
||||
},
|
||||
"rgb_matrix": {
|
||||
"animations": {
|
||||
"alphas_mods": true,
|
||||
|
@ -85,6 +93,82 @@
|
|||
},
|
||||
"center_point": [120, 36],
|
||||
"driver": "is31fl3731",
|
||||
"layout": [
|
||||
{"matrix": [0, 0], "x": 0, "y": 4, "flags": 1},
|
||||
{"matrix": [1, 0], "x": 0, "y": 20, "flags": 1},
|
||||
{"matrix": [2, 0], "x": 0, "y": 36, "flags": 1},
|
||||
{"matrix": [3, 0], "x": 0, "y": 52, "flags": 1},
|
||||
{"matrix": [4, 0], "x": 0, "y": 68, "flags": 1},
|
||||
{"matrix": [0, 1], "x": 16, "y": 3, "flags": 4},
|
||||
{"matrix": [1, 1], "x": 16, "y": 19, "flags": 4},
|
||||
{"matrix": [2, 1], "x": 16, "y": 35, "flags": 4},
|
||||
{"matrix": [3, 1], "x": 16, "y": 51, "flags": 4},
|
||||
{"matrix": [4, 1], "x": 16, "y": 67, "flags": 1},
|
||||
{"matrix": [0, 2], "x": 32, "y": 1, "flags": 4},
|
||||
{"matrix": [1, 2], "x": 32, "y": 17, "flags": 4},
|
||||
{"matrix": [2, 2], "x": 32, "y": 33, "flags": 4},
|
||||
{"matrix": [3, 2], "x": 32, "y": 49, "flags": 4},
|
||||
{"matrix": [4, 2], "x": 32, "y": 65, "flags": 1},
|
||||
{"matrix": [0, 3], "x": 48, "y": 0, "flags": 4},
|
||||
{"matrix": [1, 3], "x": 48, "y": 16, "flags": 4},
|
||||
{"matrix": [2, 3], "x": 48, "y": 32, "flags": 4},
|
||||
{"matrix": [3, 3], "x": 48, "y": 48, "flags": 4},
|
||||
{"matrix": [4, 3], "x": 48, "y": 64, "flags": 1},
|
||||
{"matrix": [0, 4], "x": 64, "y": 1, "flags": 4},
|
||||
{"matrix": [1, 4], "x": 64, "y": 17, "flags": 4},
|
||||
{"matrix": [2, 4], "x": 64, "y": 33, "flags": 4},
|
||||
{"matrix": [3, 4], "x": 64, "y": 49, "flags": 4},
|
||||
{"matrix": [4, 4], "x": 64, "y": 65, "flags": 1},
|
||||
{"matrix": [0, 5], "x": 80, "y": 3, "flags": 4},
|
||||
{"matrix": [1, 5], "x": 80, "y": 19, "flags": 4},
|
||||
{"matrix": [2, 5], "x": 80, "y": 35, "flags": 4},
|
||||
{"matrix": [3, 5], "x": 80, "y": 51, "flags": 4},
|
||||
{"matrix": [0, 6], "x": 96, "y": 4, "flags": 1},
|
||||
{"matrix": [1, 6], "x": 96, "y": 20, "flags": 1},
|
||||
{"matrix": [2, 6], "x": 96, "y": 36, "flags": 1},
|
||||
{"matrix": [5, 0], "x": 88, "y": 69, "flags": 1},
|
||||
{"matrix": [5, 1], "x": 100, "y": 80, "flags": 1},
|
||||
{"matrix": [5, 2], "x": 112, "y": 91, "flags": 1},
|
||||
{"matrix": [5, 3], "x": 108, "y": 69, "flags": 1},
|
||||
{"matrix": [6, 6], "x": 240, "y": 4, "flags": 1},
|
||||
{"matrix": [7, 6], "x": 240, "y": 20, "flags": 1},
|
||||
{"matrix": [8, 6], "x": 240, "y": 36, "flags": 1},
|
||||
{"matrix": [9, 6], "x": 240, "y": 52, "flags": 1},
|
||||
{"matrix": [10, 6], "x": 240, "y": 68, "flags": 1},
|
||||
{"matrix": [6, 5], "x": 224, "y": 3, "flags": 4},
|
||||
{"matrix": [7, 5], "x": 224, "y": 19, "flags": 4},
|
||||
{"matrix": [8, 5], "x": 224, "y": 35, "flags": 4},
|
||||
{"matrix": [9, 5], "x": 224, "y": 51, "flags": 4},
|
||||
{"matrix": [10, 5], "x": 224, "y": 67, "flags": 1},
|
||||
{"matrix": [6, 4], "x": 208, "y": 1, "flags": 4},
|
||||
{"matrix": [7, 4], "x": 208, "y": 17, "flags": 4},
|
||||
{"matrix": [8, 4], "x": 208, "y": 33, "flags": 4},
|
||||
{"matrix": [9, 4], "x": 208, "y": 49, "flags": 4},
|
||||
{"matrix": [10, 4], "x": 208, "y": 65, "flags": 1},
|
||||
{"matrix": [6, 3], "x": 192, "y": 0, "flags": 4},
|
||||
{"matrix": [7, 3], "x": 192, "y": 16, "flags": 4},
|
||||
{"matrix": [8, 3], "x": 192, "y": 32, "flags": 4},
|
||||
{"matrix": [9, 3], "x": 192, "y": 48, "flags": 4},
|
||||
{"matrix": [10, 3], "x": 192, "y": 64, "flags": 1},
|
||||
{"matrix": [6, 2], "x": 176, "y": 1, "flags": 4},
|
||||
{"matrix": [7, 2], "x": 176, "y": 17, "flags": 4},
|
||||
{"matrix": [8, 2], "x": 176, "y": 33, "flags": 4},
|
||||
{"matrix": [9, 2], "x": 176, "y": 49, "flags": 4},
|
||||
{"matrix": [10, 2], "x": 176, "y": 65, "flags": 1},
|
||||
{"matrix": [6, 1], "x": 160, "y": 3, "flags": 4},
|
||||
{"matrix": [7, 1], "x": 160, "y": 19, "flags": 4},
|
||||
{"matrix": [8, 1], "x": 160, "y": 35, "flags": 4},
|
||||
{"matrix": [9, 1], "x": 160, "y": 51, "flags": 4},
|
||||
{"matrix": [6, 0], "x": 144, "y": 4, "flags": 1},
|
||||
{"matrix": [7, 0], "x": 144, "y": 20, "flags": 1},
|
||||
{"matrix": [8, 0], "x": 144, "y": 36, "flags": 1},
|
||||
{"matrix": [11, 6], "x": 152, "y": 69, "flags": 1},
|
||||
{"matrix": [11, 5], "x": 140, "y": 80, "flags": 1},
|
||||
{"matrix": [11, 4], "x": 128, "y": 91, "flags": 1},
|
||||
{"matrix": [11, 3], "x": 132, "y": 69, "flags": 1}
|
||||
],
|
||||
"led_flush_limit": 26,
|
||||
"led_process_limit": 5,
|
||||
"max_brightness": 175,
|
||||
"sleep": true
|
||||
},
|
||||
|
|
85
keyboards/zsa/moonlander/ld/STM32F303xB.ld
Normal file
85
keyboards/zsa/moonlander/ld/STM32F303xB.ld
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* STM32F303xB memory setup.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
flash0 (rx) : org = 0x08000000, len = 128k
|
||||
flash1 (rx) : org = 0x00000000, len = 0
|
||||
flash2 (rx) : org = 0x00000000, len = 0
|
||||
flash3 (rx) : org = 0x00000000, len = 0
|
||||
flash4 (rx) : org = 0x00000000, len = 0
|
||||
flash5 (rx) : org = 0x00000000, len = 0
|
||||
flash6 (rx) : org = 0x00000000, len = 0
|
||||
flash7 (rx) : org = 0x00000000, len = 0
|
||||
ram0 (wx) : org = 0x20000000, len = 32k
|
||||
ram1 (wx) : org = 0x00000000, len = 0
|
||||
ram2 (wx) : org = 0x00000000, len = 0
|
||||
ram3 (wx) : org = 0x00000000, len = 0
|
||||
ram4 (wx) : org = 0x10000000, len = 8k
|
||||
ram5 (wx) : org = 0x00000000, len = 0
|
||||
ram6 (wx) : org = 0x00000000, len = 0
|
||||
ram7 (wx) : org = 0x00000000, len = 0
|
||||
}
|
||||
|
||||
/* For each data/text section two region are defined, a virtual region
|
||||
and a load region (_LMA suffix).*/
|
||||
|
||||
/* Flash region to be used for exception vectors.*/
|
||||
REGION_ALIAS("VECTORS_FLASH", flash0);
|
||||
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for constructors and destructors.*/
|
||||
REGION_ALIAS("XTORS_FLASH", flash0);
|
||||
REGION_ALIAS("XTORS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for code text.*/
|
||||
REGION_ALIAS("TEXT_FLASH", flash0);
|
||||
REGION_ALIAS("TEXT_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for read only data.*/
|
||||
REGION_ALIAS("RODATA_FLASH", flash0);
|
||||
REGION_ALIAS("RODATA_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for various.*/
|
||||
REGION_ALIAS("VARIOUS_FLASH", flash0);
|
||||
REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
|
||||
|
||||
/* Flash region to be used for RAM(n) initialization data.*/
|
||||
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
|
||||
|
||||
/* RAM region to be used for Main stack. This stack accommodates the processing
|
||||
of all exceptions and interrupts.*/
|
||||
REGION_ALIAS("MAIN_STACK_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for the process stack. This is the stack used by
|
||||
the main() function.*/
|
||||
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for data segment.*/
|
||||
REGION_ALIAS("DATA_RAM", ram0);
|
||||
REGION_ALIAS("DATA_RAM_LMA", flash0);
|
||||
|
||||
/* RAM region to be used for BSS segment.*/
|
||||
REGION_ALIAS("BSS_RAM", ram0);
|
||||
|
||||
/* RAM region to be used for the default heap.*/
|
||||
REGION_ALIAS("HEAP_RAM", ram0);
|
||||
|
||||
/* Generic rules inclusion.*/
|
||||
INCLUDE rules.ld
|
|
@ -14,62 +14,39 @@
|
|||
*
|
||||
* 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 "moonlander.h"
|
||||
#include "i2c_master.h"
|
||||
#include "mcp23018.h"
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("-O3")
|
||||
/*
|
||||
#define MATRIX_ROW_PINS { B10, B11, B12, B13, B14, B15 } outputs
|
||||
#define MATRIX_COL_PINS { A0, A1, A2, A3, A6, A7, B0 } inputs
|
||||
#define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 } outputs
|
||||
#define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 } inputs
|
||||
|
||||
*/
|
||||
/* matrix state(1:on, 0:off) */
|
||||
extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
|
||||
extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
|
||||
static matrix_row_t raw_matrix_right[MATRIX_COLS];
|
||||
extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
|
||||
extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
|
||||
static matrix_row_t raw_matrix_right[MATRIX_ROWS];
|
||||
|
||||
#define ROWS_PER_HAND (MATRIX_ROWS / 2)
|
||||
#ifndef MOONLANDER_I2C_TIMEOUT
|
||||
# define MOONLANDER_I2C_TIMEOUT 100
|
||||
#endif
|
||||
#define MCP_ROWS_PER_HAND (MATRIX_ROWS / 2)
|
||||
|
||||
extern bool mcp23018_leds[3];
|
||||
extern bool is_launching;
|
||||
|
||||
bool mcp23018_initd = false;
|
||||
static uint8_t mcp23018_reset_loop;
|
||||
static uint16_t mcp23018_reset_loop;
|
||||
uint8_t mcp23018_errors;
|
||||
|
||||
uint8_t mcp23018_tx[3];
|
||||
uint8_t mcp23018_rx[1];
|
||||
|
||||
void mcp23018_init(void) {
|
||||
i2c_init();
|
||||
|
||||
// #define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 } outputs
|
||||
// #define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 } inputs
|
||||
|
||||
mcp23018_tx[0] = 0x00; // IODIRA
|
||||
mcp23018_tx[1] = 0b00000000; // A is output
|
||||
mcp23018_tx[2] = 0b00111111; // B is inputs
|
||||
|
||||
if (MSG_OK != i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, MOONLANDER_I2C_TIMEOUT)) {
|
||||
dprintf("error hori\n");
|
||||
} else {
|
||||
mcp23018_tx[0] = 0x0C; // GPPUA
|
||||
mcp23018_tx[1] = 0b10000000; // A is not pulled-up
|
||||
mcp23018_tx[2] = 0b11111111; // B is pulled-up
|
||||
|
||||
if (MSG_OK != i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, MOONLANDER_I2C_TIMEOUT)) {
|
||||
dprintf("error hori\n");
|
||||
} else {
|
||||
mcp23018_initd = is_launching = true;
|
||||
}
|
||||
}
|
||||
bool io_expander_ready(void) {
|
||||
uint8_t tx;
|
||||
return mcp23018_read_pins(MCP23018_DEFAULT_ADDRESS, mcp23018_PORTA, &tx);
|
||||
}
|
||||
|
||||
void matrix_init_custom(void) {
|
||||
dprintf("matrix init\n");
|
||||
// debug_matrix = true;
|
||||
// outputs
|
||||
gpio_set_pin_output(B10);
|
||||
gpio_set_pin_output(B11);
|
||||
|
@ -87,115 +64,116 @@ void matrix_init_custom(void) {
|
|||
gpio_set_pin_input_low(A7);
|
||||
gpio_set_pin_input_low(B0);
|
||||
|
||||
mcp23018_init();
|
||||
mcp23018_init(MCP23018_DEFAULT_ADDRESS);
|
||||
mcp23018_errors += !mcp23018_set_config(MCP23018_DEFAULT_ADDRESS, mcp23018_PORTA, 0b00000000);
|
||||
mcp23018_errors += !mcp23018_set_config(MCP23018_DEFAULT_ADDRESS, mcp23018_PORTB, 0b00111111);
|
||||
|
||||
if (!mcp23018_errors) {
|
||||
is_launching = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
|
||||
bool changed = false;
|
||||
|
||||
// Try to re-init right side
|
||||
if (!mcp23018_initd) {
|
||||
if (++mcp23018_reset_loop == 0) {
|
||||
// if (++mcp23018_reset_loop >= 1300) {
|
||||
// since mcp23018_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
|
||||
print("trying to reset mcp23018\n");
|
||||
mcp23018_init();
|
||||
if (!mcp23018_initd) {
|
||||
print("right side not responding\n");
|
||||
} else {
|
||||
print("right side attached\n");
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
rgb_matrix_init();
|
||||
#endif
|
||||
// Attempt to reset the mcp23018 if it's not initialized
|
||||
if (mcp23018_errors) {
|
||||
if (++mcp23018_reset_loop > 0x1FFF) {
|
||||
if (io_expander_ready()) {
|
||||
// If we managed to initialize the mcp23018 - we need to reinitialize the matrix / layer state. During an electric discharge the i2c peripherals might be in a weird state. Giving a delay and resetting the MCU allows to recover from this.
|
||||
wait_ms(200);
|
||||
mcu_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matrix_row_t data = 0;
|
||||
// actual matrix
|
||||
for (uint8_t row = 0; row <= ROWS_PER_HAND; row++) {
|
||||
for (uint8_t row = 0; row <= MCP_ROWS_PER_HAND; row++) {
|
||||
// strobe row
|
||||
switch (row) {
|
||||
case 0: gpio_write_pin_high(B10); break;
|
||||
case 1: gpio_write_pin_high(B11); break;
|
||||
case 2: gpio_write_pin_high(B12); break;
|
||||
case 3: gpio_write_pin_high(B13); break;
|
||||
case 4: gpio_write_pin_high(B14); break;
|
||||
case 5: gpio_write_pin_high(B15); break;
|
||||
case 6: break; // Left hand has 6 rows
|
||||
case 0:
|
||||
gpio_write_pin_high(B10);
|
||||
break;
|
||||
case 1:
|
||||
gpio_write_pin_high(B11);
|
||||
break;
|
||||
case 2:
|
||||
gpio_write_pin_high(B12);
|
||||
break;
|
||||
case 3:
|
||||
gpio_write_pin_high(B13);
|
||||
break;
|
||||
case 4:
|
||||
gpio_write_pin_high(B14);
|
||||
break;
|
||||
case 5:
|
||||
gpio_write_pin_high(B15);
|
||||
break;
|
||||
case 6:
|
||||
break; // Left hand has 6 rows
|
||||
}
|
||||
|
||||
// right side
|
||||
if (mcp23018_initd) {
|
||||
// #define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 } outputs
|
||||
// #define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 } inputs
|
||||
|
||||
// Selecting the row on the right side of the keyboard.
|
||||
if (!mcp23018_errors) {
|
||||
// select row
|
||||
mcp23018_tx[0] = 0x12; // GPIOA
|
||||
mcp23018_tx[1] = (0b01111111 & ~(1 << (row))) | ((uint8_t)!mcp23018_leds[2] << 7); // activate row
|
||||
mcp23018_tx[2] = ((uint8_t)!mcp23018_leds[1] << 6) | ((uint8_t)!mcp23018_leds[0] << 7); // activate row
|
||||
mcp23018_errors += !mcp23018_set_output_all(MCP23018_DEFAULT_ADDRESS, (0b01111111 & ~(1 << (row))) | ((uint8_t)!mcp23018_leds[2] << 7), ((uint8_t)!mcp23018_leds[1] << 6) | ((uint8_t)!mcp23018_leds[0] << 7));
|
||||
}
|
||||
|
||||
if (MSG_OK != i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, MOONLANDER_I2C_TIMEOUT)) {
|
||||
dprintf("error hori\n");
|
||||
mcp23018_initd = false;
|
||||
// Reading the left side of the keyboard.
|
||||
if (row < MCP_ROWS_PER_HAND) {
|
||||
// i2c comm incur enough wait time
|
||||
if (mcp23018_errors) {
|
||||
// need wait to settle pin state
|
||||
matrix_io_delay();
|
||||
}
|
||||
// read col data
|
||||
data = ((readPin(A0) << 0) | (readPin(A1) << 1) | (readPin(A2) << 2) | (readPin(A3) << 3) | (readPin(A6) << 4) | (readPin(A7) << 5) | (readPin(B0) << 6));
|
||||
// unstrobe row
|
||||
switch (row) {
|
||||
case 0:
|
||||
gpio_write_pin_low(B10);
|
||||
break;
|
||||
case 1:
|
||||
gpio_write_pin_low(B11);
|
||||
break;
|
||||
case 2:
|
||||
gpio_write_pin_low(B12);
|
||||
break;
|
||||
case 3:
|
||||
gpio_write_pin_low(B13);
|
||||
break;
|
||||
case 4:
|
||||
gpio_write_pin_low(B14);
|
||||
break;
|
||||
case 5:
|
||||
gpio_write_pin_low(B15);
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
|
||||
// read col
|
||||
|
||||
mcp23018_tx[0] = 0x13; // GPIOB
|
||||
if (MSG_OK != i2c_read_register(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx[0], &mcp23018_rx[0], 1, MOONLANDER_I2C_TIMEOUT)) {
|
||||
dprintf("error vert\n");
|
||||
mcp23018_initd = false;
|
||||
if (current_matrix[row] != data) {
|
||||
current_matrix[row] = data;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
data = ~(mcp23018_rx[0] & 0b00111111);
|
||||
// data = 0x01;
|
||||
// Reading the right side of the keyboard.
|
||||
if (!mcp23018_errors) {
|
||||
uint8_t rx;
|
||||
mcp23018_errors += !mcp23018_read_pins(MCP23018_DEFAULT_ADDRESS, mcp23018_PORTB, &rx);
|
||||
data = ~(rx & 0b00111111);
|
||||
} else {
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if (raw_matrix_right[row] != data) {
|
||||
raw_matrix_right[row] = data;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
// left side
|
||||
if (row < ROWS_PER_HAND) {
|
||||
// i2c comm incur enough wait time
|
||||
if (!mcp23018_initd) {
|
||||
// need wait to settle pin state
|
||||
matrix_io_delay();
|
||||
}
|
||||
// read col data
|
||||
data = (
|
||||
(gpio_read_pin(A0) << 0 ) |
|
||||
(gpio_read_pin(A1) << 1 ) |
|
||||
(gpio_read_pin(A2) << 2 ) |
|
||||
(gpio_read_pin(A3) << 3 ) |
|
||||
(gpio_read_pin(A6) << 4 ) |
|
||||
(gpio_read_pin(A7) << 5 ) |
|
||||
(gpio_read_pin(B0) << 6 )
|
||||
);
|
||||
// unstrobe row
|
||||
switch (row) {
|
||||
case 0: gpio_write_pin_low(B10); break;
|
||||
case 1: gpio_write_pin_low(B11); break;
|
||||
case 2: gpio_write_pin_low(B12); break;
|
||||
case 3: gpio_write_pin_low(B13); break;
|
||||
case 4: gpio_write_pin_low(B14); break;
|
||||
case 5: gpio_write_pin_low(B15); break;
|
||||
case 6: break;
|
||||
}
|
||||
|
||||
if (current_matrix[row] != data) {
|
||||
current_matrix[row] = data;
|
||||
changed = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
for (uint8_t row = 0; row < ROWS_PER_HAND; row++) {
|
||||
|
||||
for (uint8_t row = 0; row < MCP_ROWS_PER_HAND; row++) {
|
||||
current_matrix[11 - row] = 0;
|
||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
|
||||
current_matrix[11 - row] |= ((raw_matrix_right[6 - col] & (1 << row) ? 1 : 0) << col);
|
||||
|
@ -222,12 +200,12 @@ void matrix_power_up(void) {
|
|||
}
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool is_transport_connected(void) {
|
||||
return mcp23018_initd;
|
||||
}
|
||||
return (bool)(mcp23018_errors == 0);
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
#undef STM32_I2C_USE_I2C1
|
||||
#define STM32_I2C_USE_I2C1 TRUE
|
||||
|
||||
// for future hardwar
|
||||
#undef STM32_I2C_USE_I2C2
|
||||
#define STM32_I2C_USE_I2C2 TRUE
|
||||
|
||||
// for audio
|
||||
#undef STM32_DAC_USE_DAC1_CH1
|
||||
#define STM32_DAC_USE_DAC1_CH1 TRUE
|
||||
|
@ -33,7 +29,3 @@
|
|||
#define STM32_DAC_USE_DAC1_CH2 TRUE
|
||||
#undef STM32_GPT_USE_TIM6
|
||||
#define STM32_GPT_USE_TIM6 TRUE
|
||||
#undef STM32_GPT_USE_TIM7
|
||||
#define STM32_GPT_USE_TIM7 TRUE
|
||||
#undef STM32_GPT_USE_TIM8
|
||||
#define STM32_GPT_USE_TIM8 TRUE
|
||||
|
|
|
@ -23,87 +23,96 @@ keyboard_config_t keyboard_config;
|
|||
bool mcp23018_leds[3] = {0, 0, 0};
|
||||
bool is_launching = false;
|
||||
|
||||
#ifdef DYNAMIC_MACRO_ENABLE
|
||||
static bool is_dynamic_recording = false;
|
||||
#if defined(DEFERRED_EXEC_ENABLE)
|
||||
# if defined(DYNAMIC_MACRO_ENABLE)
|
||||
deferred_token dynamic_macro_token = INVALID_DEFERRED_TOKEN;
|
||||
|
||||
static uint32_t dynamic_macro_led(uint32_t trigger_time, void *cb_arg) {
|
||||
static bool led_state = true;
|
||||
if (!is_launching) {
|
||||
led_state = !led_state;
|
||||
ML_LED_3(led_state);
|
||||
}
|
||||
return 100;
|
||||
}
|
||||
|
||||
bool dynamic_macro_record_start_kb(int8_t direction) {
|
||||
if (!dynamic_macro_record_start_user(direction)) {
|
||||
return false;
|
||||
}
|
||||
is_dynamic_recording = true;
|
||||
return true;
|
||||
if (dynamic_macro_token == INVALID_DEFERRED_TOKEN) {
|
||||
ML_LED_3(true);
|
||||
dynamic_macro_token = defer_exec(100, dynamic_macro_led, NULL);
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
bool dynamic_macro_record_end_kb(int8_t direction) {
|
||||
if (!dynamic_macro_record_end_user(direction)) {
|
||||
return false;
|
||||
}
|
||||
is_dynamic_recording = false;
|
||||
ML_LED_3(false);
|
||||
return false;
|
||||
if (cancel_deferred_exec(dynamic_macro_token)) {
|
||||
dynamic_macro_token = INVALID_DEFERRED_TOKEN;
|
||||
ML_LED_3(false);
|
||||
}
|
||||
return false
|
||||
}
|
||||
# endif
|
||||
|
||||
static uint32_t startup_exec(uint32_t trigger_time, void *cb_arg) {
|
||||
static uint8_t startup_loop = 0;
|
||||
|
||||
switch (startup_loop++) {
|
||||
case 0:
|
||||
ML_LED_1(true);
|
||||
ML_LED_2(false);
|
||||
ML_LED_3(false);
|
||||
ML_LED_4(false);
|
||||
ML_LED_5(false);
|
||||
ML_LED_6(false);
|
||||
break;
|
||||
case 1:
|
||||
ML_LED_2(true);
|
||||
break;
|
||||
case 2:
|
||||
ML_LED_3(true);
|
||||
break;
|
||||
case 3:
|
||||
ML_LED_4(true);
|
||||
break;
|
||||
case 4:
|
||||
ML_LED_5(true);
|
||||
break;
|
||||
case 5:
|
||||
ML_LED_6(true);
|
||||
break;
|
||||
case 6:
|
||||
ML_LED_1(false);
|
||||
break;
|
||||
case 7:
|
||||
ML_LED_2(false);
|
||||
break;
|
||||
case 8:
|
||||
ML_LED_3(false);
|
||||
break;
|
||||
case 9:
|
||||
ML_LED_4(false);
|
||||
break;
|
||||
case 10:
|
||||
ML_LED_5(false);
|
||||
break;
|
||||
case 11:
|
||||
ML_LED_6(false);
|
||||
break;
|
||||
case 12:
|
||||
is_launching = false;
|
||||
layer_state_set_kb(layer_state);
|
||||
return 0;
|
||||
}
|
||||
return 250;
|
||||
}
|
||||
#endif
|
||||
|
||||
void moonlander_led_task(void) {
|
||||
if (is_launching) {
|
||||
ML_LED_1(false);
|
||||
ML_LED_2(false);
|
||||
ML_LED_3(false);
|
||||
ML_LED_4(false);
|
||||
ML_LED_5(false);
|
||||
ML_LED_6(false);
|
||||
|
||||
ML_LED_1(true);
|
||||
wait_ms(250);
|
||||
ML_LED_2(true);
|
||||
wait_ms(250);
|
||||
ML_LED_3(true);
|
||||
wait_ms(250);
|
||||
ML_LED_4(true);
|
||||
wait_ms(250);
|
||||
ML_LED_5(true);
|
||||
wait_ms(250);
|
||||
ML_LED_6(true);
|
||||
wait_ms(250);
|
||||
ML_LED_1(false);
|
||||
wait_ms(250);
|
||||
ML_LED_2(false);
|
||||
wait_ms(250);
|
||||
ML_LED_3(false);
|
||||
wait_ms(250);
|
||||
ML_LED_4(false);
|
||||
wait_ms(250);
|
||||
ML_LED_5(false);
|
||||
wait_ms(250);
|
||||
ML_LED_6(false);
|
||||
wait_ms(250);
|
||||
is_launching = false;
|
||||
layer_state_set_kb(layer_state);
|
||||
}
|
||||
#ifdef DYNAMIC_MACRO_ENABLE
|
||||
else if (is_dynamic_recording) {
|
||||
ML_LED_3(true);
|
||||
wait_ms(100);
|
||||
ML_LED_3(false);
|
||||
wait_ms(155);
|
||||
}
|
||||
#endif
|
||||
#if !defined(MOONLANDER_USER_LEDS)
|
||||
else {
|
||||
layer_state_set_kb(layer_state);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static THD_WORKING_AREA(waLEDThread, 128);
|
||||
static THD_FUNCTION(LEDThread, arg) {
|
||||
(void)arg;
|
||||
chRegSetThreadName("LEDThread");
|
||||
while (true) {
|
||||
moonlander_led_task();
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_pre_init_kb(void) {
|
||||
gpio_set_pin_output(B5);
|
||||
gpio_set_pin_output(B4);
|
||||
|
@ -113,13 +122,6 @@ void keyboard_pre_init_kb(void) {
|
|||
gpio_write_pin_low(B4);
|
||||
gpio_write_pin_low(B3);
|
||||
|
||||
chThdCreateStatic(waLEDThread, sizeof(waLEDThread), NORMALPRIO - 16, LEDThread, NULL);
|
||||
|
||||
/* the array is initialized to 0, no need to re-set it here */
|
||||
// mcp23018_leds[0] = 0; // blue
|
||||
// mcp23018_leds[1] = 0; // green
|
||||
// mcp23018_leds[2] = 0; // red
|
||||
|
||||
keyboard_pre_init_user();
|
||||
}
|
||||
|
||||
|
@ -183,13 +185,7 @@ layer_state_t layer_state_set_kb(layer_state_t state) {
|
|||
#ifdef RGB_MATRIX_ENABLE
|
||||
// clang-format off
|
||||
const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
||||
/* Refer to IS31 manual for these locations
|
||||
* driver
|
||||
* | R location
|
||||
* | | G location
|
||||
* | | | B location
|
||||
* | | | | */
|
||||
{0, C3_2, C1_1, C4_2}, // 1
|
||||
{0, C3_2, C1_1, C4_2},
|
||||
{0, C2_2, C1_2, C4_3},
|
||||
{0, C2_3, C1_3, C3_3},
|
||||
{0, C2_4, C1_4, C3_4},
|
||||
|
@ -199,7 +195,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{0, C2_8, C1_8, C3_8},
|
||||
{0, C3_1, C2_1, C4_1},
|
||||
|
||||
{0, C7_8, C6_8, C8_8}, // 10
|
||||
{0, C7_8, C6_8, C8_8},
|
||||
{0, C7_7, C6_7, C9_8},
|
||||
{0, C8_7, C6_6, C9_7},
|
||||
{0, C8_6, C7_6, C9_6},
|
||||
|
@ -209,7 +205,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{0, C8_2, C7_2, C9_2},
|
||||
{0, C8_1, C7_1, C9_1},
|
||||
|
||||
{0, C3_10, C1_9, C4_10}, // 19
|
||||
{0, C3_10, C1_9, C4_10},
|
||||
{0, C2_10, C1_10, C4_11},
|
||||
{0, C2_11, C1_11, C3_11},
|
||||
{0, C2_12, C1_12, C3_12},
|
||||
|
@ -219,7 +215,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{0, C2_16, C1_16, C3_16},
|
||||
{0, C3_9, C2_9, C4_9},
|
||||
|
||||
{0, C7_16, C6_16, C8_16}, // 28
|
||||
{0, C7_16, C6_16, C8_16},
|
||||
{0, C7_15, C6_15, C9_16},
|
||||
{0, C8_15, C6_14, C9_15},
|
||||
{0, C8_10, C7_10, C9_10},
|
||||
|
@ -229,7 +225,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{0, C8_13, C7_13, C9_13},
|
||||
{0, C8_14, C7_14, C9_14},
|
||||
|
||||
{1, C3_2, C1_1, C4_2}, // 1
|
||||
{1, C3_2, C1_1, C4_2},
|
||||
{1, C2_2, C1_2, C4_3},
|
||||
{1, C2_3, C1_3, C3_3},
|
||||
{1, C2_4, C1_4, C3_4},
|
||||
|
@ -239,7 +235,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{1, C2_8, C1_8, C3_8},
|
||||
{1, C3_1, C2_1, C4_1},
|
||||
|
||||
{1, C7_8, C6_8, C8_8}, // 10
|
||||
{1, C7_8, C6_8, C8_8},
|
||||
{1, C7_7, C6_7, C9_8},
|
||||
{1, C8_7, C6_6, C9_7},
|
||||
{1, C8_6, C7_6, C9_6},
|
||||
|
@ -249,7 +245,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{1, C8_2, C7_2, C9_2},
|
||||
{1, C8_1, C7_1, C9_1},
|
||||
|
||||
{1, C3_10, C1_9, C4_10}, // 19
|
||||
{1, C3_10, C1_9, C4_10},
|
||||
{1, C2_10, C1_10, C4_11},
|
||||
{1, C2_11, C1_11, C3_11},
|
||||
{1, C2_12, C1_12, C3_12},
|
||||
|
@ -259,7 +255,7 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{1, C2_16, C1_16, C3_16},
|
||||
{1, C3_9, C2_9, C4_9},
|
||||
|
||||
{1, C7_16, C6_16, C8_16}, // 28
|
||||
{1, C7_16, C6_16, C8_16},
|
||||
{1, C7_15, C6_15, C9_16},
|
||||
{1, C8_15, C6_14, C9_15},
|
||||
{1, C8_10, C7_10, C9_10},
|
||||
|
@ -268,61 +264,8 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
|
|||
{1, C8_12, C7_12, C9_12},
|
||||
{1, C8_13, C7_13, C9_13},
|
||||
{1, C8_14, C7_14, C9_14},
|
||||
|
||||
};
|
||||
|
||||
led_config_t g_led_config = { {
|
||||
{ 0, 5, 10, 15, 20, 25, 29 },
|
||||
{ 1, 6, 11, 16, 21, 26, 30 },
|
||||
{ 2, 7, 12, 17, 22, 27, 31 },
|
||||
{ 3, 8, 13, 18, 23, 28, NO_LED },
|
||||
{ 4, 9, 14, 19, 24, NO_LED, NO_LED },
|
||||
{ 32, 33, 34, 35, NO_LED, NO_LED, NO_LED },
|
||||
{ 65, 61, 56, 51, 46, 41, 36 },
|
||||
{ 66, 62, 57, 52, 47, 42, 37 },
|
||||
{ 67, 63, 58, 53, 48, 43, 38 },
|
||||
{ NO_LED, 64, 59, 54, 49, 44, 39 },
|
||||
{ NO_LED, NO_LED, 60, 55, 50, 45, 40 },
|
||||
{ NO_LED, NO_LED, NO_LED, 71, 70, 69, 68 }
|
||||
}, {
|
||||
{ 0, 4}, { 0, 20}, { 0, 36}, { 0, 52}, { 0, 68},
|
||||
{ 16, 3}, { 16, 19}, { 16, 35}, { 16, 51}, { 16, 67},
|
||||
{ 32, 1}, { 32, 17}, { 32, 33}, { 32, 49}, { 32, 65},
|
||||
{ 48, 0}, { 48, 16}, { 48, 32}, { 48, 48}, { 48, 64},
|
||||
{ 64, 1}, { 64, 17}, { 64, 33}, { 64, 49}, { 64, 65},
|
||||
{ 80, 3}, { 80, 19}, { 80, 35}, { 80, 51},
|
||||
{ 96, 4}, { 96, 20}, { 96, 36},
|
||||
{ 88, 69}, {100, 80}, {112, 91}, {108, 69},
|
||||
|
||||
{240, 4}, {240, 20}, {240, 36}, {240, 52}, {240, 68},
|
||||
{224, 3}, {224, 19}, {224, 35}, {224, 51}, {224, 67},
|
||||
{208, 1}, {208, 17}, {208, 33}, {208, 49}, {208, 65},
|
||||
{192, 0}, {192, 16}, {192, 32}, {192, 48}, {192, 64},
|
||||
{176, 1}, {176, 17}, {176, 33}, {176, 49}, {176, 65},
|
||||
{160, 3}, {160, 19}, {160, 35}, {160, 51},
|
||||
{144, 4}, {144, 20}, {144, 36},
|
||||
{152, 69}, {140, 80}, {128, 91}, {132, 69}
|
||||
}, {
|
||||
1, 1, 1, 1, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4,
|
||||
1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
|
||||
1, 1, 1, 1, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4, 1,
|
||||
4, 4, 4, 4,
|
||||
1, 1, 1,
|
||||
1, 1, 1, 1
|
||||
} };
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef AUDIO_ENABLE
|
||||
|
@ -368,11 +311,6 @@ const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
|
|||
{{6,5}, {5,5}, {4,5}, {3,5}, {2,5}, {1,5},{0,5}},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
void keyboard_post_init_kb(void) {
|
||||
rgb_matrix_enable_noeeprom();
|
||||
keyboard_post_init_user();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_ENABLE) && defined(MUSIC_MAP)
|
||||
|
@ -451,7 +389,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
void keyboard_post_init_kb(void) {
|
||||
keyboard_config.raw = eeconfig_read_kb();
|
||||
|
||||
if (!keyboard_config.led_level && !keyboard_config.led_level_res) {
|
||||
|
@ -460,11 +398,11 @@ void matrix_init_kb(void) {
|
|||
eeconfig_update_kb(keyboard_config.raw);
|
||||
}
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
if (keyboard_config.rgb_matrix_enable) {
|
||||
rgb_matrix_set_flags(LED_FLAG_ALL);
|
||||
} else {
|
||||
rgb_matrix_set_flags(LED_FLAG_NONE);
|
||||
}
|
||||
rgb_matrix_enable_noeeprom();
|
||||
#endif
|
||||
#if defined(DEFERRED_EXEC_ENABLE)
|
||||
is_launching = true;
|
||||
defer_exec(500, startup_exec, NULL);
|
||||
#endif
|
||||
matrix_init_user();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
CUSTOM_MATRIX = lite
|
||||
|
||||
# project specific files
|
||||
SRC += matrix.c
|
||||
VPATH += drivers/gpio
|
||||
SRC += matrix.c mcp23018.c
|
||||
I2C_DRIVER_REQUIRED = yes
|
||||
|
||||
MCU_LDSCRIPT = STM32F303xB
|
||||
|
|
Loading…
Reference in a new issue