Directly connected LED Matrix support.
This adds support for LEDs that are directly connected to the MCU, either in a matrix or to single pins.
This commit is contained in:
parent
a5a31a5fc0
commit
f8896d8b92
21 changed files with 478 additions and 81 deletions
|
@ -116,7 +116,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 IS31FL3737 WS2812 custom
|
VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 IS31FL3737 WS2812 custom pins pinmatrix
|
||||||
|
|
||||||
LED_MATRIX_ENABLE ?= no
|
LED_MATRIX_ENABLE ?= no
|
||||||
ifneq ($(strip $(LED_MATRIX_ENABLE)), no)
|
ifneq ($(strip $(LED_MATRIX_ENABLE)), no)
|
||||||
|
@ -129,6 +129,20 @@ ifneq ($(strip $(LED_MATRIX_ENABLE)), no)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_ENABLE)), pinmatrix)
|
||||||
|
CIE1931_CURVE = yes
|
||||||
|
OPT_DEFS += -DLED_MATRIX_PINMATRIX_ENABLE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led
|
||||||
|
SRC += led_matrix_pinmatrix.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_ENABLE)), pins)
|
||||||
|
CIE1931_CURVE = yes
|
||||||
|
OPT_DEFS += -DLED_MATRIX_PINS_ENABLE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led
|
||||||
|
SRC += led_matrix_pins.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_ENABLE)), IS31FL3731)
|
ifeq ($(strip $(LED_MATRIX_ENABLE)), IS31FL3731)
|
||||||
OPT_DEFS += -DIS31FL3731
|
OPT_DEFS += -DIS31FL3731
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/issi
|
COMMON_VPATH += $(DRIVER_PATH)/issi
|
||||||
|
|
|
@ -1,10 +1,66 @@
|
||||||
# LED Matrix Lighting
|
# LED Matrix Lighting
|
||||||
|
|
||||||
This feature allows you to use LED matrices driven by external drivers. It hooks into the backlight system so you can use the same keycodes as backlighting to control it.
|
This feature allows you to use LED matrices driven by external drivers. It hooks into the [backlight subsystem](feature_backlight.md) so you can use the same keycodes as backlighting to control it. Many of the same configuration settings apply as well.
|
||||||
|
|
||||||
If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_rgb_matrix.md) instead.
|
If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_rgb_matrix.md) instead.
|
||||||
|
|
||||||
## Driver configuration
|
LED Matrix supports LEDs that are connected directly to the MCU and LEDs connected to an external controller IC (such as the IS31FL3731 from ISSI.)
|
||||||
|
|
||||||
|
## Directly Connected LEDs
|
||||||
|
|
||||||
|
There are two ways that LEDs can be connected to the LED Matrix-
|
||||||
|
|
||||||
|
* Direct Pin: One pin per LED
|
||||||
|
* Direct Pin Matrix: LED matrix with rows and columns
|
||||||
|
|
||||||
|
### Direct Pin
|
||||||
|
|
||||||
|
This driver uses LEDs that are connected directly to to a pin on the PCB. If you are not familiar with how to wire an LED directly to a microcontroller you can [follow this guide](https://create.arduino.cc/projecthub/rowan07/make-a-simple-led-circuit-ce8308). The process is similar for every microcontroller that QMK supports.
|
||||||
|
|
||||||
|
You can configure the driver to either source or sink current, but that setting applies to all LEDs.
|
||||||
|
|
||||||
|
Settings needed in `rules.mk`:
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `BACKLIGHT_ENABLE = yes` | Turn on the backlight subsystem |
|
||||||
|
| `LED_MATRIX_ENABLE = pins` | Enable the LED Matrix subsystem and configure it for directly connected LEDs |
|
||||||
|
|
||||||
|
Settings needed in `config.h`:
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| `LED_MATRIX_PINS` | A list of pins with connected LEDs. | `{ }` |
|
||||||
|
| `LED_DRIVER_LED_COUNT` | The number of LEDs connected to pins |
|
||||||
|
|
||||||
|
### Direct Pin Matrix
|
||||||
|
|
||||||
|
This driver supports driving an LED matrix that is connected directly to the local controller in a common-row cathode orientation. For more general information on LED matrices and how to design them there are several useful outside resources:
|
||||||
|
|
||||||
|
* https://www.circuitspecialists.com/blog/build-8x8-led-matrix/
|
||||||
|
* https://www.instructables.com/id/Make-Your-Own-LED-Matrix-/
|
||||||
|
* https://appelsiini.net/2011/how-does-led-matrix-work/
|
||||||
|
|
||||||
|
Settings needed in `rules.mk`:
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `BACKLIGHT_ENABLE = yes` | Turn on the backlight subsystem |
|
||||||
|
| `LED_MATRIX_ENABLE = pinmatrix` | Enable the LED Matrix subsystem and configure it for a matrix |
|
||||||
|
|
||||||
|
Settings needed in `config.h`:
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| `LED_DRIVER_LED_COUNT` | (Required) How many LED lights are present | (none) |
|
||||||
|
| `LED_MATRIX_COLS` | (Required) The number of columns (current sources) your matrix has | (none) |
|
||||||
|
| `LED_MATRIX_COL_PINS` | (Required) A list of column pins, EG `{ B1, B2, B3, B4 }`| (none) |
|
||||||
|
| `LED_MATRIX_ROWS` | (Required) The number of rows (current sinks) your matrix has | (none) |
|
||||||
|
| `LED_MATRIX_ROW_PINS` | (Required) A list of row pins, EG `{ B5, B6, B7, B8 }` | (none) |
|
||||||
|
|
||||||
|
## LED Driver ICs
|
||||||
|
|
||||||
|
You can also use an LED driver chip. The IS31 series of ICs is popular and well supported in QMK.
|
||||||
|
|
||||||
### IS31FL3731
|
### IS31FL3731
|
||||||
|
|
||||||
|
|
103
drivers/led/led_matrix_pinmatrix.c
Normal file
103
drivers/led/led_matrix_pinmatrix.c
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2019 Clueboard
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
# include <avr/interrupt.h>
|
||||||
|
# include <avr/io.h>
|
||||||
|
# include <util/delay.h>
|
||||||
|
# define led_wait_us(us) wait_us(us)
|
||||||
|
#else
|
||||||
|
# include "ch.h"
|
||||||
|
# include "hal.h"
|
||||||
|
# define led_wait_us(us) chSysPolledDelayX(US2RTC(STM32_SYSCLK, us))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "led_matrix_pinmatrix.h"
|
||||||
|
#include "led_tables.h"
|
||||||
|
#include "progmem.h"
|
||||||
|
#include "quantum.h"
|
||||||
|
#include "backlight.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_pwm_buffer is an array that represents the duty cycle (0-255) for each LED.
|
||||||
|
* FIXME: Map this from the wiring matrix to a physical location matrix at some point
|
||||||
|
*/
|
||||||
|
uint8_t g_pwm_buffer[LED_MATRIX_ROWS * LED_MATRIX_COLS];
|
||||||
|
const pin_t led_row_pins[LED_MATRIX_ROWS] = LED_MATRIX_ROW_PINS;
|
||||||
|
const pin_t led_col_pins[LED_MATRIX_COLS] = LED_MATRIX_COL_PINS;
|
||||||
|
|
||||||
|
|
||||||
|
void led_matrix_pinmatrix_init_pins(void) {
|
||||||
|
/* Set all pins to output, we are not interested in reading any information.
|
||||||
|
*/
|
||||||
|
for (uint8_t x = 0; x < LED_MATRIX_ROWS; x++) {
|
||||||
|
setPinOutput(led_row_pins[x]);
|
||||||
|
writePinLow(led_row_pins[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t x = 0; x < LED_MATRIX_COLS; x++) {
|
||||||
|
setPinOutput(led_col_pins[x]);
|
||||||
|
writePinLow(led_col_pins[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_matrix_pinmatrix_set_value(int index, uint8_t value) {
|
||||||
|
/* Set the brighness for a single LED.
|
||||||
|
*/
|
||||||
|
if (index >= 0 && index < LED_DRIVER_LED_COUNT) {
|
||||||
|
g_pwm_buffer[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_matrix_pinmatrix_set_value_all(uint8_t value) {
|
||||||
|
/* Set the brighness for all LEDs.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < LED_DRIVER_LED_COUNT; i++) {
|
||||||
|
led_matrix_pinmatrix_set_value(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_matrix_pinmatrix_flush(void) {
|
||||||
|
/* This is a basic bit-banged pwm implementation.
|
||||||
|
*/
|
||||||
|
uint8_t led_count = 0;
|
||||||
|
for (uint8_t row = 0; row < LED_MATRIX_ROWS; row++) {
|
||||||
|
writePinLow(led_row_pins[row]);
|
||||||
|
for (uint8_t col = 0; col < LED_MATRIX_COLS; col++) {
|
||||||
|
/* We spend ~128us on each LED, dividing that time between lit and unlit.
|
||||||
|
*/
|
||||||
|
const uint8_t brightness = pgm_read_byte(&CIE1931_CURVE[g_pwm_buffer[led_count]]) / 2;
|
||||||
|
if (brightness > 0) {
|
||||||
|
writePinHigh(led_col_pins[col]);
|
||||||
|
for (int i = 0; i < 128; i++) {
|
||||||
|
if (i == brightness) {
|
||||||
|
writePinLow(led_col_pins[col]);
|
||||||
|
}
|
||||||
|
led_wait_us(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
led_wait_us(128);
|
||||||
|
}
|
||||||
|
led_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
drivers/led/led_matrix_pinmatrix.h
Normal file
30
drivers/led/led_matrix_pinmatrix.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2019 Clueboard
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LED_MATRIX_PINMATRIX_DRIVER_H
|
||||||
|
#define LED_MATRIX_PINMATRIX_DRIVER_H
|
||||||
|
|
||||||
|
void led_matrix_pinmatrix_init_pins(void);
|
||||||
|
void led_matrix_pinmatrix_set_value(int index, uint8_t value);
|
||||||
|
void led_matrix_pinmatrix_set_value_all(uint8_t value);
|
||||||
|
void led_matrix_pinmatrix_flush(void);
|
||||||
|
void led_matrix_pinmatrix_select_row(uint8_t row);
|
||||||
|
void led_matrix_pinmatrix_unselect_row(uint8_t row);
|
||||||
|
void led_matrix_pinmatrix_unselect_rows(void);
|
||||||
|
|
||||||
|
#endif // LED_MATRIX_PINMATRIX_DRIVER_H
|
95
drivers/led/led_matrix_pins.c
Normal file
95
drivers/led/led_matrix_pins.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2019 Clueboard
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
# include <avr/interrupt.h>
|
||||||
|
# include <avr/io.h>
|
||||||
|
# include <util/delay.h>
|
||||||
|
# define led_wait_us(us) wait_us(us)
|
||||||
|
#else
|
||||||
|
# include "ch.h"
|
||||||
|
# include "hal.h"
|
||||||
|
# define led_wait_us(us) chSysPolledDelayX(US2RTC(STM32_SYSCLK, us))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "led_matrix_pins.h"
|
||||||
|
#include "led_tables.h"
|
||||||
|
#include "progmem.h"
|
||||||
|
#include "quantum.h"
|
||||||
|
#include "backlight.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_pwm_buffer is an array that represents the duty cycle (0-255) for each LED.
|
||||||
|
*/
|
||||||
|
uint8_t g_pwm_buffer[LED_DRIVER_LED_COUNT];
|
||||||
|
const pin_t led_pins[LED_DRIVER_LED_COUNT] = LED_MATRIX_PINS;
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PIN_SINK
|
||||||
|
# define led_pin_on(pin) writePinLow(pin)
|
||||||
|
# define led_pin_off(pin) writePinHigh(pin)
|
||||||
|
#else
|
||||||
|
# define led_pin_on(pin) writePinHigh(pin)
|
||||||
|
# define led_pin_off(pin) writePinLow(pin)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void led_matrix_pins_init_pins(void) {
|
||||||
|
/* Set all pins to output, we are not interested in reading any information.
|
||||||
|
*/
|
||||||
|
for (uint8_t x = 0; x < LED_DRIVER_LED_COUNT; x++) {
|
||||||
|
setPinOutput(led_pins[x]);
|
||||||
|
led_pin_off(led_pins[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_matrix_pins_set_value(int index, uint8_t value) {
|
||||||
|
/* Set the brighness for a single LED.
|
||||||
|
*/
|
||||||
|
if (index >= 0 && index < LED_DRIVER_LED_COUNT) {
|
||||||
|
g_pwm_buffer[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_matrix_pins_set_value_all(uint8_t value) {
|
||||||
|
/* Set the brighness for all LEDs.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < LED_DRIVER_LED_COUNT; i++) {
|
||||||
|
led_matrix_pins_set_value(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_matrix_pins_flush(void) {
|
||||||
|
/* This is a basic bit-banged pwm implementation.
|
||||||
|
*/
|
||||||
|
for (uint8_t i = 0; i < LED_DRIVER_LED_COUNT; i++) {
|
||||||
|
/* We spend ~1.3ms on each LED, dividing that time between lit and unlit.
|
||||||
|
*/
|
||||||
|
if (g_pwm_buffer[i] > 0) {
|
||||||
|
uint8_t brightness = pgm_read_byte(&CIE1931_CURVE[g_pwm_buffer[i]]) / 2;
|
||||||
|
led_pin_on(led_pins[i]);
|
||||||
|
led_wait_us(brightness);
|
||||||
|
led_pin_off(led_pins[i]);
|
||||||
|
led_wait_us(128 - brightness);
|
||||||
|
} else {
|
||||||
|
led_wait_us(128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
drivers/led/led_matrix_pins.h
Normal file
30
drivers/led/led_matrix_pins.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2019 Clueboard
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LED_MATRIX_PINS_DRIVER_H
|
||||||
|
#define LED_MATRIX_PINS_DRIVER_H
|
||||||
|
|
||||||
|
void led_matrix_pins_init_pins(void);
|
||||||
|
void led_matrix_pins_set_value(int index, uint8_t value);
|
||||||
|
void led_matrix_pins_set_value_all(uint8_t value);
|
||||||
|
void led_matrix_pins_flush(void);
|
||||||
|
void led_matrix_pins_select_row(uint8_t row);
|
||||||
|
void led_matrix_pins_unselect_row(uint8_t row);
|
||||||
|
void led_matrix_pins_unselect_rows(void);
|
||||||
|
|
||||||
|
#endif // LED_MATRIX_PINS_DRIVER_H
|
39
keyboards/1upkeyboards/sweet16/keymaps/tester/keymap.c
Normal file
39
keyboards/1upkeyboards/sweet16/keymaps/tester/keymap.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
|
enum custom_keycodes {
|
||||||
|
UP_URL = SAFE_RANGE
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
LAYOUT_ortho_4x4(
|
||||||
|
KC_0, KC_1, KC_2, KC_3,
|
||||||
|
KC_4, KC_5, KC_6, KC_7,
|
||||||
|
KC_8, KC_9, KC_A, KC_B,
|
||||||
|
KC_C, RESET, KC_E, BL_STEP
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case UP_URL:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
SEND_STRING("http://1upkeyboards.com");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENCODER_ENABLE
|
||||||
|
#include "encoder.h"
|
||||||
|
void encoder_update_user(int8_t index, bool clockwise) {
|
||||||
|
if (index == 0) { /* First encoder */
|
||||||
|
if (clockwise) {
|
||||||
|
tap_code(KC_VOLU);
|
||||||
|
} else {
|
||||||
|
tap_code(KC_VOLD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1 +0,0 @@
|
||||||
#include "sweet16.h"
|
|
|
@ -1,30 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "quantum.h"
|
|
||||||
|
|
||||||
// Any changes to the layout names and/or definitions must also be made to info.json
|
|
||||||
|
|
||||||
#define LAYOUT_ortho_4x4( \
|
|
||||||
K00, K01, K02, K03, \
|
|
||||||
K10, K11, K12, K13, \
|
|
||||||
K20, K21, K22, K23, \
|
|
||||||
K30, K31, K32, K33 \
|
|
||||||
) { \
|
|
||||||
{ K00, K01, K02, K03 }, \
|
|
||||||
{ K10, K11, K12, K13 }, \
|
|
||||||
{ K20, K21, K22, K23 }, \
|
|
||||||
{ K30, K31, K32, K33 } \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LAYOUT_numpad_4x4( \
|
|
||||||
K00, K01, K02, K03, \
|
|
||||||
K10, K11, K12, \
|
|
||||||
K20, K21, K22, K23, \
|
|
||||||
K31, K32 \
|
|
||||||
) { \
|
|
||||||
{ K00, K01, K02, K03 }, \
|
|
||||||
{ K10, K11, K12, KC_NO }, \
|
|
||||||
{ K20, K21, K22, K23 }, \
|
|
||||||
{ KC_NO, K31, K32, KC_NO } \
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,6 +17,14 @@
|
||||||
/* Set 0 if debouncing isn't needed */
|
/* Set 0 if debouncing isn't needed */
|
||||||
#define DEBOUNCE 5
|
#define DEBOUNCE 5
|
||||||
|
|
||||||
|
/* Backlight configuration
|
||||||
|
*/
|
||||||
|
#define LED_MATRIX_ROWS 4
|
||||||
|
#define LED_MATRIX_ROW_PINS { B1, B3, B2, B4 }
|
||||||
|
#define LED_MATRIX_COLS 4
|
||||||
|
#define LED_MATRIX_COL_PINS { B6, D0, C6, D7 }
|
||||||
|
#define LED_DRIVER_LED_COUNT 16
|
||||||
|
|
||||||
/* Encoder pins */
|
/* Encoder pins */
|
||||||
#define ENCODERS_PAD_A { F4 }
|
#define ENCODERS_PAD_A { F4 }
|
||||||
#define ENCODERS_PAD_B { F5 }
|
#define ENCODERS_PAD_B { F5 }
|
||||||
|
|
|
@ -3,6 +3,8 @@ BOOTLOADER = caterina
|
||||||
LINK_TIME_OPTIMIZATION_ENABLE=yes
|
LINK_TIME_OPTIMIZATION_ENABLE=yes
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
BACKLIGHT_ENABLE = yes
|
||||||
|
LED_MATRIX_ENABLE = pinmatrix
|
||||||
CONSOLE_ENABLE = yes
|
CONSOLE_ENABLE = yes
|
||||||
|
|
||||||
## On a Pro Micro you have to choose between underglow and the rotary encoder.
|
## On a Pro Micro you have to choose between underglow and the rotary encoder.
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
/* COL2ROW or ROW2COL */
|
/* COL2ROW or ROW2COL */
|
||||||
#define DIODE_DIRECTION ROW2COL
|
#define DIODE_DIRECTION ROW2COL
|
||||||
|
|
||||||
|
/* Backlight configuration
|
||||||
|
*/
|
||||||
|
#define LED_MATRIX_ROWS 4
|
||||||
|
#define LED_MATRIX_ROW_PINS { B13, B14, B15, B1 }
|
||||||
|
#define LED_MATRIX_COLS 4
|
||||||
|
#define LED_MATRIX_COL_PINS { B9, B6, B4, B3 }
|
||||||
|
#define LED_DRIVER_LED_COUNT 16
|
||||||
|
|
||||||
/* Encoder pins */
|
/* Encoder pins */
|
||||||
#define ENCODERS_PAD_A { A2 }
|
#define ENCODERS_PAD_A { A2 }
|
||||||
#define ENCODERS_PAD_B { A1 }
|
#define ENCODERS_PAD_B { A1 }
|
||||||
|
|
|
@ -2,5 +2,7 @@ MCU = STM32F303
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
CONSOLE_ENABLE = yes
|
CONSOLE_ENABLE = yes
|
||||||
|
BACKLIGHT_ENABLE = yes
|
||||||
|
LED_MATRIX_ENABLE = pinmatrix
|
||||||
ENCODER_ENABLE = yes
|
ENCODER_ENABLE = yes
|
||||||
AUDIO_ENABLE = yes
|
AUDIO_ENABLE = yes
|
||||||
|
|
|
@ -22,3 +22,9 @@
|
||||||
{ NO_PIN, B2 } \
|
{ NO_PIN, B2 } \
|
||||||
}
|
}
|
||||||
#define UNUSED_PINS
|
#define UNUSED_PINS
|
||||||
|
|
||||||
|
/* Backlight configuration
|
||||||
|
*/
|
||||||
|
#define BACKLIGHT_LEVELS 10
|
||||||
|
#define LED_MATRIX_PINS { A2, B5, A1, B4, B12, B10, A15, A6, B0, B3 }
|
||||||
|
#define LED_DRIVER_LED_COUNT 10
|
||||||
|
|
|
@ -6,5 +6,7 @@ EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||||
CONSOLE_ENABLE = yes # Console for debug
|
CONSOLE_ENABLE = yes # Console for debug
|
||||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
COMMAND_ENABLE = no # Commands for debug and configuration
|
||||||
NKRO_ENABLE = yes # USB Nkey Rollover
|
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||||
|
BACKLIGHT_ENABLE = yes
|
||||||
|
LED_MATRIX_ENABLE = pins
|
||||||
RGBLIGHT_ENABLE = no
|
RGBLIGHT_ENABLE = no
|
||||||
AUDIO_ENABLE = yes
|
AUDIO_ENABLE = yes
|
||||||
|
|
|
@ -96,7 +96,6 @@ def format_ansi(text):
|
||||||
class ANSIFormatter(logging.Formatter):
|
class ANSIFormatter(logging.Formatter):
|
||||||
"""A log formatter that inserts ANSI color.
|
"""A log formatter that inserts ANSI color.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def format(self, record):
|
def format(self, record):
|
||||||
msg = super(ANSIFormatter, self).format(record)
|
msg = super(ANSIFormatter, self).format(record)
|
||||||
return format_ansi(msg)
|
return format_ansi(msg)
|
||||||
|
@ -105,7 +104,6 @@ class ANSIFormatter(logging.Formatter):
|
||||||
class ANSIEmojiLoglevelFormatter(ANSIFormatter):
|
class ANSIEmojiLoglevelFormatter(ANSIFormatter):
|
||||||
"""A log formatter that makes the loglevel an emoji on UTF capable terminals.
|
"""A log formatter that makes the loglevel an emoji on UTF capable terminals.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def format(self, record):
|
def format(self, record):
|
||||||
if UNICODE_SUPPORT:
|
if UNICODE_SUPPORT:
|
||||||
record.levelname = EMOJI_LOGLEVELS[record.levelname].format(**ansi_colors)
|
record.levelname = EMOJI_LOGLEVELS[record.levelname].format(**ansi_colors)
|
||||||
|
@ -115,7 +113,6 @@ class ANSIEmojiLoglevelFormatter(ANSIFormatter):
|
||||||
class ANSIStrippingFormatter(ANSIFormatter):
|
class ANSIStrippingFormatter(ANSIFormatter):
|
||||||
"""A log formatter that strips ANSI.
|
"""A log formatter that strips ANSI.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def format(self, record):
|
def format(self, record):
|
||||||
msg = super(ANSIStrippingFormatter, self).format(record)
|
msg = super(ANSIStrippingFormatter, self).format(record)
|
||||||
return ansi_escape.sub('', msg)
|
return ansi_escape.sub('', msg)
|
||||||
|
@ -127,7 +124,6 @@ class Configuration(object):
|
||||||
This class never raises IndexError, instead it will return None if a
|
This class never raises IndexError, instead it will return None if a
|
||||||
section or option does not yet exist.
|
section or option does not yet exist.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return self._config.__contains__(key)
|
return self._config.__contains__(key)
|
||||||
|
|
||||||
|
@ -216,7 +212,6 @@ def handle_store_boolean(self, *args, **kwargs):
|
||||||
class SubparserWrapper(object):
|
class SubparserWrapper(object):
|
||||||
"""Wrap subparsers so we can populate the normal and the shadow parser.
|
"""Wrap subparsers so we can populate the normal and the shadow parser.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, cli, submodule, subparser):
|
def __init__(self, cli, submodule, subparser):
|
||||||
self.cli = cli
|
self.cli = cli
|
||||||
self.submodule = submodule
|
self.submodule = submodule
|
||||||
|
@ -249,7 +244,6 @@ class SubparserWrapper(object):
|
||||||
class MILC(object):
|
class MILC(object):
|
||||||
"""MILC - An Opinionated Batteries Included Framework
|
"""MILC - An Opinionated Batteries Included Framework
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initialize the MILC object.
|
"""Initialize the MILC object.
|
||||||
"""
|
"""
|
||||||
|
@ -620,7 +614,6 @@ class MILC(object):
|
||||||
def subcommand(self, description, **kwargs):
|
def subcommand(self, description, **kwargs):
|
||||||
"""Decorator to register a subcommand.
|
"""Decorator to register a subcommand.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def subcommand_function(handler):
|
def subcommand_function(handler):
|
||||||
return self.add_subcommand(handler, description, **kwargs)
|
return self.add_subcommand(handler, description, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import glob
|
||||||
|
|
||||||
from milc import cli
|
from milc import cli
|
||||||
|
|
||||||
|
|
||||||
@cli.subcommand("List the keyboards currently defined within QMK")
|
@cli.subcommand("List the keyboards currently defined within QMK")
|
||||||
def list_keyboards(cli):
|
def list_keyboards(cli):
|
||||||
"""List the keyboards currently defined within QMK
|
"""List the keyboards currently defined within QMK
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class NoSuchKeyboardError(Exception):
|
class NoSuchKeyboardError(Exception):
|
||||||
"""Raised when we can't find a keyboard/keymap directory.
|
"""Raised when we can't find a keyboard/keymap directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
|
@ -3,7 +3,6 @@ class AttrDict(dict):
|
||||||
|
|
||||||
This should only be used to mock objects for unit testing. Please do not use this outside of qmk.tests.
|
This should only be used to mock objects for unit testing. Please do not use this outside of qmk.tests.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(AttrDict, self).__init__(*args, **kwargs)
|
super(AttrDict, self).__init__(*args, **kwargs)
|
||||||
self.__dict__ = self
|
self.__dict__ = self
|
||||||
|
|
|
@ -35,9 +35,20 @@
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# include "i2c_master.h"
|
# include "i2c_master.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PINMATRIX_ENABLE
|
||||||
|
# include "led_matrix_pinmatrix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PINS_ENABLE
|
||||||
|
# include "led_matrix_pins.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static void init(void) {
|
static void init(void) {
|
||||||
|
#if defined(IS31FL3731) || defined(IS31FL3733)
|
||||||
i2c_init();
|
i2c_init();
|
||||||
|
|
||||||
# ifdef IS31FL3731
|
# ifdef IS31FL3731
|
||||||
# ifdef LED_DRIVER_ADDR_1
|
# ifdef LED_DRIVER_ADDR_1
|
||||||
IS31FL3731_init(LED_DRIVER_ADDR_1);
|
IS31FL3731_init(LED_DRIVER_ADDR_1);
|
||||||
|
@ -69,10 +80,12 @@ static void init(void) {
|
||||||
for (int index = 0; index < LED_DRIVER_LED_COUNT; index++) {
|
for (int index = 0; index < LED_DRIVER_LED_COUNT; index++) {
|
||||||
# ifdef IS31FL3731
|
# ifdef IS31FL3731
|
||||||
IS31FL3731_set_led_control_register(index, true);
|
IS31FL3731_set_led_control_register(index, true);
|
||||||
# else
|
# endif
|
||||||
|
# ifdef IS31FL3733
|
||||||
IS31FL3733_set_led_control_register(index, true);
|
IS31FL3733_set_led_control_register(index, true);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// This actually updates the LED drivers
|
// This actually updates the LED drivers
|
||||||
# ifdef IS31FL3731
|
# ifdef IS31FL3731
|
||||||
# ifdef LED_DRIVER_ADDR_1
|
# ifdef LED_DRIVER_ADDR_1
|
||||||
|
@ -101,6 +114,15 @@ static void init(void) {
|
||||||
IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_4, 3);
|
IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_4, 3);
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PINMATRIX_ENABLE
|
||||||
|
led_matrix_pinmatrix_init_pins();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PINS_ENABLE
|
||||||
|
led_matrix_pins_init_pins();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush(void) {
|
static void flush(void) {
|
||||||
|
@ -117,7 +139,8 @@ static void flush(void) {
|
||||||
# ifdef LED_DRIVER_ADDR_4
|
# ifdef LED_DRIVER_ADDR_4
|
||||||
IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_4, 3);
|
IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_4, 3);
|
||||||
# endif
|
# endif
|
||||||
# else
|
#endif
|
||||||
|
#ifdef IS31FL3733
|
||||||
# ifdef LED_DRIVER_ADDR_1
|
# ifdef LED_DRIVER_ADDR_1
|
||||||
IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_1, 0);
|
IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_1, 0);
|
||||||
# endif
|
# endif
|
||||||
|
@ -131,6 +154,14 @@ static void flush(void) {
|
||||||
IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_4, 3);
|
IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_4, 3);
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PINMATRIX_ENABLE
|
||||||
|
led_matrix_pinmatrix_flush();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PINS_ENABLE
|
||||||
|
led_matrix_pins_flush();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const led_matrix_driver_t led_matrix_driver = {
|
const led_matrix_driver_t led_matrix_driver = {
|
||||||
|
@ -139,10 +170,17 @@ const led_matrix_driver_t led_matrix_driver = {
|
||||||
#ifdef IS31FL3731
|
#ifdef IS31FL3731
|
||||||
.set_value = IS31FL3731_set_value,
|
.set_value = IS31FL3731_set_value,
|
||||||
.set_value_all = IS31FL3731_set_value_all,
|
.set_value_all = IS31FL3731_set_value_all,
|
||||||
# else
|
#endif
|
||||||
|
#ifdef IS31FL3133
|
||||||
.set_value = IS31FL3733_set_value,
|
.set_value = IS31FL3733_set_value,
|
||||||
.set_value_all = IS31FL3733_set_value_all,
|
.set_value_all = IS31FL3733_set_value_all,
|
||||||
#endif
|
#endif
|
||||||
};
|
#ifdef LED_MATRIX_PINMATRIX_ENABLE
|
||||||
|
.set_value = led_matrix_pinmatrix_set_value,
|
||||||
|
.set_value_all = led_matrix_pinmatrix_set_value_all,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef LED_MATRIX_PINS_ENABLE
|
||||||
|
.set_value = led_matrix_pins_set_value,
|
||||||
|
.set_value_all = led_matrix_pins_set_value_all,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
# These are defaults based on what has been implemented for ARM boards
|
# These are defaults based on what has been implemented for ARM boards
|
||||||
AUDIO_ENABLE = yes
|
AUDIO_ENABLE = yes
|
||||||
RGBLIGHT_ENABLE = no
|
RGBLIGHT_ENABLE = no
|
||||||
|
|
||||||
|
ifneq ($(strip $(LED_MATRIX_ENABLE)), direct)
|
||||||
BACKLIGHT_ENABLE = no
|
BACKLIGHT_ENABLE = no
|
||||||
|
endif
|
||||||
|
|
||||||
# The rest of these settings shouldn't change
|
# The rest of these settings shouldn't change
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue