Migrate keyboards using uGFX to LED_MATRIX (#9657)

This commit is contained in:
Joakim Tufvegren 2021-06-10 09:46:09 +02:00 committed by GitHub
parent b2fdd48744
commit 6fe3943ad3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 362 additions and 98 deletions

View file

@ -62,6 +62,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LED_BRIGHTNESS_LO 100 #define LED_BRIGHTNESS_LO 100
#define LED_BRIGHTNESS_HI 255 #define LED_BRIGHTNESS_HI 255
/* LED matrix driver */
#define LED_DRIVER_ADDR_1 0x74
#define LED_DRIVER_COUNT 1
#define DRIVER_LED_TOTAL 76
#define LED_MATRIX_SPLIT { 38, 38 }
#define LED_DISABLE_WHEN_USB_SUSPENDED
/* i2c (for LED matrix) */
#define I2C1_CLOCK_SPEED 400000
#define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
#define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
#define I2C1_BANK GPIOB
#define I2C1_SCL 0
#define I2C1_SDA 1
/* define if matrix has ghost */ /* define if matrix has ghost */
//#define MATRIX_HAS_GHOST //#define MATRIX_HAS_GHOST

View file

@ -1,20 +1,45 @@
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include <ch.h> #include <ch.h>
#include <hal.h> #include <hal.h>
#include <string.h>
#include "eeconfig.h"
#include "serial_link/system/serial_link.h" #include "serial_link/system/serial_link.h"
#ifdef VISUALIZER_ENABLE #ifdef VISUALIZER_ENABLE
#include "lcd_backlight.h" # include "lcd_backlight.h"
#endif #endif
#ifdef WPM_ENABLE #if (defined(LED_MATRIX_ENABLE) || defined(WPM_ENABLE))
# include "serial_link/protocol/transport.h" # include "serial_link/protocol/transport.h"
# include "wpm.h"
# ifdef LED_MATRIX_ENABLE
MASTER_TO_ALL_SLAVES_OBJECT(led_matrix, led_eeconfig_t);
MASTER_TO_ALL_SLAVES_OBJECT(led_suspend_state, bool);
static led_eeconfig_t last_sent_led_matrix;
static uint16_t led_matrix_sent_timer = 0;
void send_led_suspend_state(void) {
if (is_serial_link_master()) {
*begin_write_led_suspend_state() = led_matrix_get_suspend_state();
end_write_led_suspend_state();
}
}
# endif
# ifdef WPM_ENABLE
# include "wpm.h"
MASTER_TO_ALL_SLAVES_OBJECT(current_wpm, uint8_t); MASTER_TO_ALL_SLAVES_OBJECT(current_wpm, uint8_t);
static remote_object_t* remote_objects[] = {
REMOTE_OBJECT(current_wpm),
};
static uint8_t last_sent_wpm = 0; static uint8_t last_sent_wpm = 0;
# endif
static remote_object_t *remote_objects[] = {
# ifdef LED_MATRIX_ENABLE
REMOTE_OBJECT(led_matrix),
REMOTE_OBJECT(led_suspend_state),
# endif
# ifdef WPM_ENABLE
REMOTE_OBJECT(current_wpm),
# endif
};
#endif #endif
void init_serial_link_hal(void) { void init_serial_link_hal(void) {
@ -52,7 +77,7 @@ void init_serial_link_hal(void) {
void lcd_backlight_hal_init(void) { void lcd_backlight_hal_init(void) {
// Setup Backlight // Setup Backlight
SIM->SCGC6 |= SIM_SCGC6_FTM0; SIM->SCGC6 |= SIM_SCGC6_FTM0;
FTM0->CNT = 0; // Reset counter FTM0->CNT = 0; // Reset counter
// PWM Period // PWM Period
// 16-bit maximum // 16-bit maximum
@ -60,25 +85,25 @@ void lcd_backlight_hal_init(void) {
// Set FTM to PWM output - Edge Aligned, Low-true pulses // Set FTM to PWM output - Edge Aligned, Low-true pulses
#define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0) #define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0)
CHANNEL_RED.CnSC = CNSC_MODE; CHANNEL_RED.CnSC = CNSC_MODE;
CHANNEL_GREEN.CnSC = CNSC_MODE; CHANNEL_GREEN.CnSC = CNSC_MODE;
CHANNEL_BLUE.CnSC = CNSC_MODE; CHANNEL_BLUE.CnSC = CNSC_MODE;
// System clock, /w prescalar setting // System clock, /w prescalar setting
FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE); FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE);
CHANNEL_RED.CnV = 0; CHANNEL_RED.CnV = 0;
CHANNEL_GREEN.CnV = 0; CHANNEL_GREEN.CnV = 0;
CHANNEL_BLUE.CnV = 0; CHANNEL_BLUE.CnV = 0;
RGB_PORT_GPIO->PDDR |= (1 << RED_PIN); RGB_PORT_GPIO->PDDR |= (1 << RED_PIN);
RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN); RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN);
RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN); RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN);
#define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4) #define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4)
RGB_PORT->PCR[RED_PIN] = RGB_MODE; RGB_PORT->PCR[RED_PIN] = RGB_MODE;
RGB_PORT->PCR[GREEN_PIN] = RGB_MODE; RGB_PORT->PCR[GREEN_PIN] = RGB_MODE;
RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; RGB_PORT->PCR[BLUE_PIN] = RGB_MODE;
} }
static uint16_t cie_lightness(uint16_t v) { static uint16_t cie_lightness(uint16_t v) {
@ -89,12 +114,11 @@ static uint16_t cie_lightness(uint16_t v) {
// Y = (L* / 902.3) if L* <= 8 // Y = (L* / 902.3) if L* <= 8
// Y = ((L* + 16) / 116)^3 if L* > 8 // Y = ((L* + 16) / 116)^3 if L* > 8
float l = 100.0f * (v / 65535.0f); float l = 100.0f * (v / 65535.0f);
float y = 0.0f; float y = 0.0f;
if (l <= 8.0f) { if (l <= 8.0f) {
y = l / 902.3; y = l / 902.3;
} } else {
else {
y = ((l + 16.0f) / 116.0f); y = ((l + 16.0f) / 116.0f);
y = y * y * y; y = y * y * y;
if (y > 1.0f) { if (y > 1.0f) {
@ -105,31 +129,48 @@ static uint16_t cie_lightness(uint16_t v) {
} }
void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) {
CHANNEL_RED.CnV = cie_lightness(r); CHANNEL_RED.CnV = cie_lightness(r);
CHANNEL_GREEN.CnV = cie_lightness(g); CHANNEL_GREEN.CnV = cie_lightness(g);
CHANNEL_BLUE.CnV = cie_lightness(b); CHANNEL_BLUE.CnV = cie_lightness(b);
} }
__attribute__ ((weak)) __attribute__ ((weak)) void matrix_init_user(void) {}
void matrix_init_user(void) {
}
__attribute__ ((weak)) __attribute__ ((weak)) void matrix_scan_user(void) {}
void matrix_scan_user(void) {
}
void keyboard_pre_init_kb() {
#ifdef LED_MATRIX_ENABLE
// Turn on LED controller
setPinOutput(B16);
writePinHigh(B16);
#endif
keyboard_pre_init_user();
}
void matrix_init_kb(void) { void matrix_init_kb(void) {
// put your keyboard start-up code here // put your keyboard start-up code here
// runs once when the firmware starts up // runs once when the firmware starts up
#ifdef LED_MATRIX_ENABLE
/*
* Since K20x is stuck with a 32 byte EEPROM (see tmk_core/common/chibios/eeprom_teensy.c),
* and neither led_matrix_eeconfig.speed or .flags fit in this boundary, just force their values to default on boot.
*/
# if !defined(LED_MATRIX_STARTUP_SPD)
# define LED_MATRIX_STARTUP_SPD UINT8_MAX / 2
# endif
led_matrix_set_speed(LED_MATRIX_STARTUP_SPD);
led_matrix_set_flags(LED_FLAG_ALL);
#endif
matrix_init_user(); matrix_init_user();
// The backlight always has to be initialized, otherwise it will stay lit // The backlight always has to be initialized, otherwise it will stay lit
#ifndef VISUALIZER_ENABLE #ifndef VISUALIZER_ENABLE
lcd_backlight_hal_init(); lcd_backlight_hal_init();
#endif #endif
#ifdef WPM_ENABLE #if (defined(LED_MATRIX_ENABLE) || defined(WPM_ENABLE))
add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*)); add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t *));
#endif #endif
} }
@ -137,6 +178,30 @@ void matrix_scan_kb(void) {
// put your looping keyboard code here // put your looping keyboard code here
// runs every cycle (a lot) // runs every cycle (a lot)
#ifdef LED_MATRIX_ENABLE
if (is_serial_link_master()) {
if (!led_matrix_get_suspend_state()) {
if (timer_elapsed(led_matrix_sent_timer) >= 5000 || memcmp((void *)&last_sent_led_matrix, (void *)&led_matrix_eeconfig, sizeof(last_sent_led_matrix))) {
led_matrix_sent_timer = timer_read();
memcpy((void *)&last_sent_led_matrix, (void *)&led_matrix_eeconfig, sizeof(last_sent_led_matrix));
*begin_write_led_matrix() = last_sent_led_matrix;
end_write_led_matrix();
}
}
} else if (is_serial_link_connected()) {
bool *new_led_suspend_state = read_led_suspend_state();
if (new_led_suspend_state) {
led_matrix_set_suspend_state(*new_led_suspend_state);
}
if (!led_matrix_get_suspend_state()) {
led_eeconfig_t *new_led_matrix = read_led_matrix();
if (new_led_matrix) {
memcpy((void *)&led_matrix_eeconfig, (void *)new_led_matrix, sizeof(last_sent_led_matrix));
}
}
}
#endif
#ifdef WPM_ENABLE #ifdef WPM_ENABLE
if (is_serial_link_master()) { if (is_serial_link_master()) {
uint8_t current_wpm = get_current_wpm(); uint8_t current_wpm = get_current_wpm();
@ -146,67 +211,68 @@ void matrix_scan_kb(void) {
last_sent_wpm = current_wpm; last_sent_wpm = current_wpm;
} }
} else if (is_serial_link_connected()) { } else if (is_serial_link_connected()) {
uint8_t* new_wpm = read_current_wpm(); uint8_t *new_wpm = read_current_wpm();
if (new_wpm) { if (new_wpm) {
set_current_wpm(*new_wpm); set_current_wpm(*new_wpm);
} }
} }
#endif #endif
matrix_scan_user(); matrix_scan_user();
} }
bool is_keyboard_master(void) { bool is_keyboard_master(void) { return is_serial_link_master(); }
return is_serial_link_master();
bool is_keyboard_left(void) {
#if defined(EE_HANDS)
return eeconfig_read_handedness();
#elif defined(MASTER_IS_ON_RIGHT)
return !is_keyboard_master();
#else
return is_keyboard_master();
#endif
} }
__attribute__ ((weak)) __attribute__ ((weak)) void ergodox_board_led_on(void) {}
void ergodox_board_led_on(void){
__attribute__ ((weak)) void ergodox_right_led_1_on(void) {}
__attribute__ ((weak)) void ergodox_right_led_2_on(void) {}
__attribute__ ((weak)) void ergodox_right_led_3_on(void) {}
__attribute__ ((weak)) void ergodox_board_led_off(void) {}
__attribute__ ((weak)) void ergodox_right_led_1_off(void) {}
__attribute__ ((weak)) void ergodox_right_led_2_off(void) {}
__attribute__ ((weak)) void ergodox_right_led_3_off(void) {}
__attribute__ ((weak)) void ergodox_right_led_1_set(uint8_t n) {}
__attribute__ ((weak)) void ergodox_right_led_2_set(uint8_t n) {}
__attribute__ ((weak)) void ergodox_right_led_3_set(uint8_t n) {}
void suspend_power_down_kb(void) {
#ifdef LED_MATRIX_ENABLE
send_led_suspend_state();
#endif
suspend_power_down_user();
} }
__attribute__ ((weak)) void suspend_wakeup_init_kb(void) {
void ergodox_right_led_1_on(void){ #ifdef LED_MATRIX_ENABLE
} send_led_suspend_state();
#endif
__attribute__ ((weak)) suspend_wakeup_init_user();
void ergodox_right_led_2_on(void){
}
__attribute__ ((weak))
void ergodox_right_led_3_on(void){
}
__attribute__ ((weak))
void ergodox_board_led_off(void){
}
__attribute__ ((weak))
void ergodox_right_led_1_off(void){
}
__attribute__ ((weak))
void ergodox_right_led_2_off(void){
}
__attribute__ ((weak))
void ergodox_right_led_3_off(void){
}
__attribute__ ((weak))
void ergodox_right_led_1_set(uint8_t n) {
}
__attribute__ ((weak))
void ergodox_right_led_2_set(uint8_t n) {
}
__attribute__ ((weak))
void ergodox_right_led_3_set(uint8_t n) {
} }
#ifdef SWAP_HANDS_ENABLE #ifdef SWAP_HANDS_ENABLE
__attribute__ ((weak)) __attribute__ ((weak))
const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
{{0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}}, {{0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}},
{{0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}}, {{0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}},
{{0, 11}, {1, 11}, {2, 11}, {3, 11}, {4, 11}}, {{0, 11}, {1, 11}, {2, 11}, {3, 11}, {4, 11}},
{{0, 12}, {1, 12}, {2, 12}, {3, 12}, {4, 12}}, {{0, 12}, {1, 12}, {2, 12}, {3, 12}, {4, 12}},
@ -226,3 +292,115 @@ const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
{{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}}, {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}},
}; };
#endif #endif
#ifdef LED_MATRIX_ENABLE
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
// The numbers in the comments are the led numbers DXX on the PCB
/* Refer to IS31 manual for these locations
* driver
* | LED address
* | | */
// Left half
// 45 44 43 42 41 40 39
{ 0, C2_2 }, { 0, C1_2 }, { 0, C5_1 }, { 0, C4_1 }, { 0, C3_1 }, { 0, C2_1 }, { 0, C1_1 },
// 52 51 50 49 48 47 46
{ 0, C4_3 }, { 0, C3_3 }, { 0, C2_3 }, { 0, C1_3 }, { 0, C5_2 }, { 0, C4_2 }, { 0, C3_2 },
// 58 57 56 55 54 53
{ 0, C5_4 }, { 0, C4_4 }, { 0, C3_4 }, { 0, C2_4 }, { 0, C1_4 }, { 0, C5_3 },
// 67 66 65 64 63 62 61
{ 0, C4_6 }, { 0, C3_6 }, { 0, C2_6 }, { 0, C1_6 }, { 0, C5_5 }, { 0, C4_5 }, { 0, C3_5 },
// 76 75 74 73 72
{ 0, C4_8 }, { 0, C3_8 }, { 0, C2_8 }, { 0, C1_8 }, { 0, C4_7 },
// 60 59
{ 0, C2_5 }, { 0, C1_5 },
// 68
{ 0, C5_6 },
// 71 70 69
{ 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 },
// Right half (mirrored)
// Due to how LED_MATRIX_SPLIT is implemented, only the first half of g_is31_leds is actually used.
// Luckily, the right half has the same LED pinouts, just mirrored.
// 45 44 43 42 41 40 39
{ 0, C2_2 }, { 0, C1_2 }, { 0, C5_1 }, { 0, C4_1 }, { 0, C3_1 }, { 0, C2_1 }, { 0, C1_1 },
// 52 51 50 49 48 47 46
{ 0, C4_3 }, { 0, C3_3 }, { 0, C2_3 }, { 0, C1_3 }, { 0, C5_2 }, { 0, C4_2 }, { 0, C3_2 },
// 58 57 56 55 54 53
{ 0, C5_4 }, { 0, C4_4 }, { 0, C3_4 }, { 0, C2_4 }, { 0, C1_4 }, { 0, C5_3 },
// 67 66 65 64 63 62 61
{ 0, C4_6 }, { 0, C3_6 }, { 0, C2_6 }, { 0, C1_6 }, { 0, C5_5 }, { 0, C4_5 }, { 0, C3_5 },
// 76 75 74 73 72
{ 0, C4_8 }, { 0, C3_8 }, { 0, C2_8 }, { 0, C1_8 }, { 0, C4_7 },
// 60 59
{ 0, C2_5 }, { 0, C1_5 },
// 68
{ 0, C5_6 },
// 71 70 69
{ 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 },
};
led_config_t g_led_config = {
{
// Key Matrix to LED Index
// Left half
{ NO_LED, NO_LED, NO_LED, 33, 34 },
{ NO_LED, NO_LED, NO_LED, 32, 37 },
{ 6, 13, NO_LED, 26, 36 },
{ 5, 12, 19, 25, 35 },
{ 4, 11, 18, 24, 31 },
{ 3, 10, 17, 23, 30 },
{ 2, 9, 16, 22, 29 },
{ 1, 8, 15, 21, 28 },
{ 0, 7, 14, 20, 27 },
// Right half
{ NO_LED, NO_LED, NO_LED, 71, 72 },
{ NO_LED, NO_LED, NO_LED, 70, 75 },
{ 44, 51, NO_LED, 64, 74 },
{ 43, 50, 57, 63, 73 },
{ 42, 49, 56, 62, 69 },
{ 41, 48, 55, 61, 68 },
{ 40, 47, 54, 60, 67 },
{ 39, 46, 53, 59, 66 },
{ 38, 45, 52, 58, 65 },
}, {
// LED Index to Physical Position (assumes a reasonable gap between halves)
// Left half
{ 0, 3 }, { 15, 3 }, { 27, 1 }, { 39, 0 }, { 51, 1 }, { 63, 2 }, { 75, 2 },
{ 0, 13 }, { 15, 13 }, { 27, 11 }, { 39, 10 }, { 51, 11 }, { 63, 12 }, { 78, 17 },
{ 0, 23 }, { 15, 23 }, { 27, 21 }, { 39, 20 }, { 51, 21 }, { 63, 22 },
{ 0, 33 }, { 15, 33 }, { 27, 31 }, { 39, 30 }, { 51, 31 }, { 63, 32 }, { 78, 32 },
{ 4, 43 }, { 15, 43 }, { 27, 41 }, { 39, 40 }, { 51, 41 },
{ 89, 41 }, { 100, 46 },
{ 95, 55 },
{ 72, 54 }, { 83, 59 }, { 90, 64 },
// Right half (mirrored)
{ 224, 3 }, { 209, 3 }, { 197, 1 }, { 185, 0 }, { 173, 1 }, { 161, 2 }, { 149, 2 },
{ 224, 13 }, { 209, 13 }, { 197, 11 }, { 185, 10 }, { 173, 11 }, { 161, 12 }, { 146, 17 },
{ 224, 23 }, { 209, 23 }, { 197, 21 }, { 185, 20 }, { 173, 21 }, { 161, 22 },
{ 224, 33 }, { 209, 33 }, { 197, 31 }, { 185, 30 }, { 173, 31 }, { 161, 32 }, { 146, 32 },
{ 220, 43 }, { 209, 43 }, { 197, 41 }, { 185, 40 }, { 173, 41 },
{ 135, 41 }, { 124, 46 },
{ 129, 55 },
{ 152, 54 }, { 141, 59 }, { 134, 64 },
}, {
// LED Index to Flag
// Left half
1, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4,
1, 4, 4, 4, 4, 4, 1,
1, 1, 1, 1, 1,
1, 1,
1,
1, 1, 1,
// Right half (mirrored)
1, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4,
1, 4, 4, 4, 4, 4, 1,
1, 1, 1, 1, 1,
1, 1,
1,
1, 1, 1,
}
};
#endif

View file

@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "print.h" #include "print.h"
#include "debug.h" #include "debug.h"
#include "matrix.h" #include "matrix.h"
#include "eeconfig.h" #include "keyboard.h"
#include "serial_link/system/serial_link.h" #include "serial_link/system/serial_link.h"
@ -119,15 +119,9 @@ uint8_t matrix_scan(void)
} }
uint8_t offset = 0; uint8_t offset = 0;
#if (defined(EE_HANDS) || defined(MASTER_IS_ON_RIGHT)) if (is_serial_link_master() && !is_keyboard_left()) {
#ifdef EE_HANDS
if (is_serial_link_master() && !eeconfig_read_handedness()) {
#else
if (is_serial_link_master()) {
#endif
offset = MATRIX_ROWS - LOCAL_MATRIX_ROWS; offset = MATRIX_ROWS - LOCAL_MATRIX_ROWS;
} }
#endif
if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
for (int row = 0; row < LOCAL_MATRIX_ROWS; row++) { for (int row = 0; row < LOCAL_MATRIX_ROWS; row++) {
@ -167,17 +161,11 @@ void matrix_print(void)
void matrix_set_remote(matrix_row_t* rows, uint8_t index) { void matrix_set_remote(matrix_row_t* rows, uint8_t index) {
uint8_t offset = 0; uint8_t offset = 0;
#ifdef EE_HANDS if (is_keyboard_left()) {
if (eeconfig_read_handedness()) {
offset = LOCAL_MATRIX_ROWS * (index + 1); offset = LOCAL_MATRIX_ROWS * (index + 1);
} else { } else {
offset = MATRIX_ROWS - LOCAL_MATRIX_ROWS * (index + 2); offset = MATRIX_ROWS - LOCAL_MATRIX_ROWS * (index + 2);
} }
#elif defined(MASTER_IS_ON_RIGHT)
offset = MATRIX_ROWS - LOCAL_MATRIX_ROWS * (index + 2);
#else
offset = LOCAL_MATRIX_ROWS * (index + 1);
#endif
for (int row = 0; row < LOCAL_MATRIX_ROWS; row++) { for (int row = 0; row < LOCAL_MATRIX_ROWS; row++) {
matrix[offset + row] = rows[row]; matrix[offset + row] = rows[row];
} }

View file

@ -22,8 +22,6 @@ CUSTOM_MATRIX = yes # Custom matrix file
SERIAL_LINK_ENABLE = yes SERIAL_LINK_ENABLE = yes
VISUALIZER_ENABLE = yes VISUALIZER_ENABLE = yes
LCD_ENABLE = yes LCD_ENABLE = yes
BACKLIGHT_ENABLE = yes
BACKLIGHT_DRIVER = custom
LCD_BACKLIGHT_ENABLE = yes LCD_BACKLIGHT_ENABLE = yes
MIDI_ENABLE = no MIDI_ENABLE = no
RGBLIGHT_ENABLE = no RGBLIGHT_ENABLE = no
@ -32,9 +30,8 @@ LCD_DRIVER = st7565
LCD_WIDTH = 128 LCD_WIDTH = 128
LCD_HEIGHT = 32 LCD_HEIGHT = 32
LED_DRIVER = is31fl3731c LED_MATRIX_ENABLE = yes
LED_WIDTH = 7 LED_MATRIX_DRIVER = IS31FL3731
LED_HEIGHT = 7
# project specific files # project specific files
SRC = matrix.c \ SRC = matrix.c \

View file

@ -62,6 +62,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LED_BRIGHTNESS_LO 100 #define LED_BRIGHTNESS_LO 100
#define LED_BRIGHTNESS_HI 255 #define LED_BRIGHTNESS_HI 255
/* LED matrix driver */
#define LED_DRIVER_ADDR_1 0x74
#define LED_DRIVER_COUNT 1
#define DRIVER_LED_TOTAL 71
#define LED_DISABLE_WHEN_USB_SUSPENDED
/* i2c (for LED matrix) */
#define I2C1_CLOCK_SPEED 400000
#define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
#define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
#define I2C1_BANK GPIOB
#define I2C1_SCL 0
#define I2C1_SDA 1
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. /* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
* This is useful for the Windows task manager shortcut (ctrl+shift+esc). * This is useful for the Windows task manager shortcut (ctrl+shift+esc).
*/ */

View file

@ -25,16 +25,12 @@ COMMAND_ENABLE = yes # Commands for debug and configuration
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes # USB Nkey Rollover NKRO_ENABLE = yes # USB Nkey Rollover
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output AUDIO_ENABLE = no # Audio output
BACKLIGHT_DRIVER = custom
VISUALIZER_ENABLE = yes
LED_DRIVER = is31fl3731c LED_MATRIX_ENABLE = yes
LED_WIDTH = 16 LED_MATRIX_DRIVER = IS31FL3731
LED_HEIGHT = 5
LAYOUTS = 65_ansi 65_ansi_blocker 65_ansi_blocker_split_bs 65_iso 65_iso_blocker 65_iso_blocker_split_bs LAYOUTS = 65_ansi 65_ansi_blocker 65_ansi_blocker_split_bs 65_iso 65_iso_blocker 65_iso_blocker_split_bs

View file

@ -16,3 +16,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "whitefox.h" #include "whitefox.h"
#ifdef LED_MATRIX_ENABLE
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
// The numbers in the comments are the led numbers DXX on the PCB
/* Refer to IS31 manual for these locations
* driver
* | LED address
* | | */
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
{ 0, C1_1 }, { 0, C1_2 }, { 0, C1_3 }, { 0, C1_4 }, { 0, C1_5 }, { 0, C1_6 }, { 0, C1_7 }, { 0, C1_8 }, { 0, C2_1 }, { 0, C2_2 }, { 0, C2_3 }, { 0, C2_4 }, { 0, C2_5 }, { 0, C2_6 }, { 0, C2_7 }, { 0, C2_8 },
// 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
{ 0, C3_1 }, { 0, C3_2 }, { 0, C3_3 }, { 0, C3_4 }, { 0, C3_5 }, { 0, C3_6 }, { 0, C3_7 }, { 0, C3_8 }, { 0, C4_1 }, { 0, C4_2 }, { 0, C4_3 }, { 0, C4_4 }, { 0, C4_5 }, { 0, C4_6 }, { 0, C4_7 },
// 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
{ 0, C4_8 }, { 0, C5_1 }, { 0, C5_2 }, { 0, C5_3 }, { 0, C5_4 }, { 0, C5_5 }, { 0, C5_6 }, { 0, C5_7 }, { 0, C5_8 }, { 0, C6_1 }, { 0, C6_2 }, { 0, C6_3 }, { 0, C6_4 }, { 0, C6_5 }, { 0, C6_6 },
// 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
{ 0, C6_7 }, { 0, C6_8 }, { 0, C7_1 }, { 0, C7_2 }, { 0, C7_3 }, { 0, C7_4 }, { 0, C7_5 }, { 0, C7_6 }, { 0, C7_7 }, { 0, C7_8 }, { 0, C8_1 }, { 0, C8_2 }, { 0, C8_3 }, { 0, C8_4 }, { 0, C8_5 },
// 62 63 64 65 66 67 68 69 70 71
{ 0, C8_6 }, { 0, C8_7 }, { 0, C8_8 }, { 0, C9_1 }, { 0, C9_2 }, { 0, C9_3 }, { 0, C9_4 }, { 0, C9_5 }, { 0, C9_6 }, { 0, C9_7 },
};
led_config_t g_led_config = {
{
// Key Matrix to LED Index
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 },
{ 9, 10, 11, 12, 13, 14, 15, 16, 17 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26 },
{ 27, 28, 29, 30, 31, 32, 33, 34, 35 },
{ 36, 37, 38, 39, 40, 41, 42, 43, 44 },
{ 45, 46, 47, 48, 49, 50, 51, 52, 53 },
{ 54, 55, 56, 57, 58, 59, 60, 61, 62 },
{ 63, 64, 65, 66, 67, 68, 69, 70, NO_LED },
}, {
// LED Index to Physical Position
{ 0, 0 }, { 15, 0 }, { 30, 0 }, { 45, 0 }, { 60, 0 }, { 75, 0 }, { 90, 0 }, { 105, 0 }, { 119, 0 }, { 134, 0 }, { 149, 0 }, { 164, 0 }, { 179, 0 }, { 194, 0 }, { 209, 0 }, { 224, 0 },
{ 4, 16 }, { 22, 16 }, { 37, 16 }, { 52, 16 }, { 67, 16 }, { 82, 16 }, { 97, 16 }, { 112, 16 }, { 127, 16 }, { 142, 16 }, { 157, 16 }, { 172, 16 }, { 187, 16 }, { 205, 16 }, { 224, 16 },
{ 6, 32 }, { 26, 32 }, { 41, 32 }, { 56, 32 }, { 71, 32 }, { 86, 32 }, { 101, 32 }, { 116, 32 }, { 131, 32 }, { 146, 32 }, { 161, 32 }, { 175, 32 }, { 190, 32 }, { 207, 32 }, { 224, 32 },
{ 2, 48 }, { 19, 48 }, { 34, 48 }, { 49, 48 }, { 63, 48 }, { 78, 48 }, { 93, 48 }, { 108, 48 }, { 123, 48 }, { 138, 48 }, { 153, 48 }, { 168, 48 }, { 189, 48 }, { 209, 48 }, { 224, 48 },
{ 2, 64 }, { 21, 64 }, { 39, 64 }, { 95, 64 }, { 149, 64 }, { 164, 64 }, { 179, 64 }, { 194, 64 }, { 209, 64 }, { 224, 64 }
}, {
// LED Index to Flag
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
}
};
#endif
void keyboard_pre_init_kb(void) {
#ifdef LED_MATRIX_ENABLE
// Turn on LED controller
setPinOutput(B16);
writePinHigh(B16);
#endif
keyboard_pre_init_user();
}
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
#ifdef LED_MATRIX_ENABLE
/*
* Since K20x is stuck with a 32 byte EEPROM (see tmk_core/common/chibios/eeprom_teensy.c),
* and neither led_matrix_eeconfig.speed or .flags fit in this boundary, just force their values to default on boot.
*/
# if !defined(LED_MATRIX_STARTUP_SPD)
# define LED_MATRIX_STARTUP_SPD UINT8_MAX / 2
# endif
led_matrix_set_speed(LED_MATRIX_STARTUP_SPD),
led_matrix_set_flags(LED_FLAG_ALL);
#endif
matrix_init_user();
}