Merge remote-tracking branch 'origin/master' into develop

master
QMK Bot 2021-03-25 11:35:49 +00:00
commit c7436e667d
14 changed files with 1074 additions and 100 deletions

View File

@ -0,0 +1,150 @@
/* Copyright 2018 Jack Humbert
* Copyright 2018 Yiancar
*
* 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/>.
*/
/* This library is only valid for STM32 processors.
* This library follows the convention of the AVR i2c_master library.
* As a result addresses are expected to be already shifted (addr << 1).
* I2CD1 is the default driver which corresponds to pins B6 and B7. This
* can be changed.
* Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
* STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. Pins B6 and B7 are used
* but using any other I2C pins should be trivial.
*/
#ifdef RGB_MATRIX_ENABLE
#include "quantum.h"
#include "i2c_master.h"
#include <string.h>
#include <hal.h>
static uint8_t i2c_address;
I2CDriver *drivers[I2C_COUNT];
static const I2CConfig i2cconfig = {
#if defined(USE_I2CV1_CONTRIB)
I2C1_CLOCK_SPEED,
#elif defined(USE_I2CV1)
I2C1_OPMODE,
I2C1_CLOCK_SPEED,
I2C1_DUTY_CYCLE,
#else
// This configures the I2C clock to 400khz assuming a 72Mhz clock
// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) | STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL), 0, 0
#endif
};
static i2c_status_t chibios_to_qmk(const msg_t* status) {
switch (*status) {
case I2C_NO_ERROR:
return I2C_STATUS_SUCCESS;
case I2C_TIMEOUT:
return I2C_STATUS_TIMEOUT;
// I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT
default:
return I2C_STATUS_ERROR;
}
}
__attribute__((weak)) void i2c_init(I2CDriver *driver, ioportid_t scl_port, ioportid_t sda_port, iopadid_t scl_pad, iopadid_t sda_pad) {
static uint8_t index = 0;
if (index < I2C_COUNT) {
// Try releasing special pins for a short time
palSetPadMode(scl_port, scl_pad, PAL_MODE_INPUT);
palSetPadMode(sda_port, sda_pad, PAL_MODE_INPUT);
chThdSleepMilliseconds(10);
#if defined(USE_GPIOV1)
palSetPadMode(scl_port, scl_pad, I2C1_SCL_PAL_MODE);
palSetPadMode(sda_port, sda_pad, I2C1_SDA_PAL_MODE);
#else
palSetPadMode(scl_port, scl_pad, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
palSetPadMode(sda_port, sda_pad, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
#endif
drivers[index++] = driver;
}
}
i2c_status_t i2c_start(uint8_t index, uint8_t address) {
if(index >= I2C_COUNT) {
return I2C_STATUS_ERROR;
}
i2c_address = address;
i2cStart(drivers[index], &i2cconfig);
return I2C_STATUS_SUCCESS;
}
i2c_status_t i2c_transmit(uint8_t index, uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) {
if(index >= I2C_COUNT) {
return I2C_STATUS_ERROR;
}
i2c_address = address;
i2cStart(drivers[index], &i2cconfig);
msg_t status = i2cMasterTransmitTimeout(drivers[index], (i2c_address >> 1), data, length, 0, 0, TIME_MS2I(timeout));
return chibios_to_qmk(&status);
}
i2c_status_t i2c_receive(uint8_t index, uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) {
if(index >= I2C_COUNT) {
return I2C_STATUS_ERROR;
}
i2c_address = address;
i2cStart(drivers[index], &i2cconfig);
msg_t status = i2cMasterReceiveTimeout(drivers[index], (i2c_address >> 1), data, length, TIME_MS2I(timeout));
return chibios_to_qmk(&status);
}
i2c_status_t i2c_writeReg(uint8_t index, uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
if(index >= I2C_COUNT) {
return I2C_STATUS_ERROR;
}
i2c_address = devaddr;
i2cStart(drivers[index], &i2cconfig);
uint8_t complete_packet[length + 1];
for (uint8_t i = 0; i < length; i++) {
complete_packet[i + 1] = data[i];
}
complete_packet[0] = regaddr;
msg_t status = i2cMasterTransmitTimeout(drivers[index], (i2c_address >> 1), complete_packet, length + 1, 0, 0, TIME_MS2I(timeout));
return chibios_to_qmk(&status);
}
i2c_status_t i2c_readReg(uint8_t index, uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
if(index >= I2C_COUNT) {
return I2C_STATUS_ERROR;
}
i2c_address = devaddr;
i2cStart(drivers[index], &i2cconfig);
msg_t status = i2cMasterTransmitTimeout(drivers[index], (i2c_address >> 1), &regaddr, 1, data, length, TIME_MS2I(timeout));
return chibios_to_qmk(&status);
}
void i2c_stop(uint8_t index) {
if(index < I2C_COUNT) {
i2cStop(drivers[index]);
}
}
#endif

View File

@ -0,0 +1,127 @@
/* Copyright 2018 Jack Humbert
* Copyright 2018 Yiancar
*
* 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/>.
*/
/* This library follows the convention of the AVR i2c_master library.
* As a result addresses are expected to be already shifted (addr << 1).
* I2CD1 is the default driver which corresponds to pins B6 and B7. This
* can be changed.
* Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
* STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file.
*/
#pragma once
#include <ch.h>
#include <hal.h>
#ifndef I2C_COUNT
# define I2C_COUNT 1
#endif
#ifdef I2C1_BANK
# define I2C1_SCL_BANK I2C1_BANK
# define I2C1_SDA_BANK I2C1_BANK
#endif
#ifndef I2C1_SCL_BANK
# define I2C1_SCL_BANK GPIOB
#endif
#ifndef I2C1_SDA_BANK
# define I2C1_SDA_BANK GPIOB
#endif
#ifdef USE_I2C2
# ifdef I2C2_BANK
# define I2C2_SCL_BANK I2C2_BANK
# define I2C2_SDA_BANK I2C2_BANK
# endif
# ifndef I2C2_SCL_BANK
# define I2C2_SCL_BANK GPIOC
# endif
# ifndef I2C2_SDA_BANK
# define I2C2_SDA_BANK GPIOC
# endif
#endif
#ifndef I2C1_SCL
# define I2C1_SCL 6
#endif
#ifndef I2C1_SDA
# define I2C1_SDA 7
#endif
#ifdef USE_I2CV1
# ifndef I2C1_OPMODE
# define I2C1_OPMODE OPMODE_I2C
# endif
# ifndef I2C1_CLOCK_SPEED
# define I2C1_CLOCK_SPEED 100000 /* 400000 */
# endif
# ifndef I2C1_DUTY_CYCLE
# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */
# endif
#else
// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
# ifndef I2C1_TIMINGR_PRESC
# define I2C1_TIMINGR_PRESC 0U
# endif
# ifndef I2C1_TIMINGR_SCLDEL
# define I2C1_TIMINGR_SCLDEL 7U
# endif
# ifndef I2C1_TIMINGR_SDADEL
# define I2C1_TIMINGR_SDADEL 0U
# endif
# ifndef I2C1_TIMINGR_SCLH
# define I2C1_TIMINGR_SCLH 38U
# endif
# ifndef I2C1_TIMINGR_SCLL
# define I2C1_TIMINGR_SCLL 129U
# endif
#endif
#ifdef USE_GPIOV1
# ifndef I2C1_SCL_PAL_MODE
# define I2C1_SCL_PAL_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
# endif
# ifndef I2C1_SDA_PAL_MODE
# define I2C1_SDA_PAL_MODE PAL_MODE_STM32_ALTERNATE_OPENDRAIN
# endif
#else
// The default PAL alternate modes are used to signal that the pins are used for I2C
# ifndef I2C1_SCL_PAL_MODE
# define I2C1_SCL_PAL_MODE 4
# endif
# ifndef I2C1_SDA_PAL_MODE
# define I2C1_SDA_PAL_MODE 4
# endif
#endif
typedef int16_t i2c_status_t;
#define I2C_STATUS_SUCCESS (0)
#define I2C_STATUS_ERROR (-1)
#define I2C_STATUS_TIMEOUT (-2)
void i2c_init(I2CDriver *driver, ioportid_t scl_port, ioportid_t sda_port, iopadid_t scl_pad, iopadid_t sda_pad);
i2c_status_t i2c_start(uint8_t index, uint8_t address);
i2c_status_t i2c_transmit(uint8_t index, uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_receive(uint8_t index, uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_writeReg(uint8_t index, uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_readReg(uint8_t index, uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
void i2c_stop(uint8_t index);

View File

@ -0,0 +1,236 @@
/* Copyright 2017 Jason Williams
* Copyright 2018 Jack Humbert
* Copyright 2018 Yiancar
*
* 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 RGB_MATRIX_ENABLE
#include "is31fl3733-dual.h"
#include "i2c_master.h"
#include "wait.h"
// This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol)
// The address will vary depending on your wiring:
// 00 <-> GND
// 01 <-> SCL
// 10 <-> SDA
// 11 <-> VCC
// ADDR1 represents A1:A0 of the 7-bit address.
// ADDR2 represents A3:A2 of the 7-bit address.
// The result is: 0b101(ADDR2)(ADDR1)
#define ISSI_ADDR_DEFAULT 0x50
#define ISSI_COMMANDREGISTER 0xFD
#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
#define ISSI_INTERRUPTMASKREGISTER 0xF0
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
#define ISSI_PAGE_PWM 0x01 // PG1
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
#define ISSI_PAGE_FUNCTION 0x03 // PG3
#define ISSI_REG_CONFIGURATION 0x00 // PG3
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
#define ISSI_REG_RESET 0x11 // PG3
#define ISSI_REG_SWPULLUP 0x0F // PG3
#define ISSI_REG_CSPULLUP 0x10 // PG3
#ifndef ISSI_TIMEOUT
# define ISSI_TIMEOUT 100
#endif
#ifndef ISSI_PERSISTENCE
# define ISSI_PERSISTENCE 0
#endif
// Transfer buffer for TWITransmitData()
uint8_t g_twi_transfer_buffer[20];
// These buffers match the IS31FL3733 PWM registers.
// The control buffers match the PG0 LED On/Off registers.
// Storing them like this is optimal for I2C transfers to the registers.
// We could optimize this and take out the unused registers from these
// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's
// probably not worth the extra complexity.
uint8_t g_pwm_buffer[DRIVER_COUNT][192];
bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false};
uint8_t g_led_control_registers[DRIVER_COUNT][24] = {{0}, {0}};
bool g_led_control_registers_update_required[DRIVER_COUNT] = {false};
bool IS31FL3733_write_register(uint8_t index, uint8_t addr, uint8_t reg, uint8_t data) {
// If the transaction fails function returns false.
g_twi_transfer_buffer[0] = reg;
g_twi_transfer_buffer[1] = data;
#if ISSI_PERSISTENCE > 0
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
if (i2c_transmit(index, addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) {
return false;
}
}
#else
if (i2c_transmit(index, addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) {
return false;
}
#endif
return true;
}
bool IS31FL3733_write_pwm_buffer(uint8_t index, uint8_t addr, uint8_t *pwm_buffer) {
// Assumes PG1 is already selected.
// If any of the transactions fails function returns false.
// Transmit PWM registers in 12 transfers of 16 bytes.
// g_twi_transfer_buffer[] is 20 bytes
// Iterate over the pwm_buffer contents at 16 byte intervals.
for (int i = 0; i < 192; i += 16) {
g_twi_transfer_buffer[0] = i;
// Copy the data from i to i+15.
// Device will auto-increment register for data after the first byte
// Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer.
for (int j = 0; j < 16; j++) {
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
}
#if ISSI_PERSISTENCE > 0
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
if (i2c_transmit(index, addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) {
return false;
}
}
#else
if (i2c_transmit(index, addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) {
return false;
}
#endif
}
return true;
}
void IS31FL3733_init(uint8_t bus, uint8_t addr, uint8_t sync) {
// In order to avoid the LEDs being driven with garbage data
// in the LED driver's PWM registers, shutdown is enabled last.
// Set up the mode and other settings, clear the PWM registers,
// then disable software shutdown.
// Sync is passed so set it according to the datasheet.
// Unlock the command register.
IS31FL3733_write_register(bus, addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
// Select PG0
IS31FL3733_write_register(bus, addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL);
// Turn off all LEDs.
for (int i = 0x00; i <= 0x17; i++) {
IS31FL3733_write_register(bus, addr, i, 0x00);
}
// Unlock the command register.
IS31FL3733_write_register(bus, addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
// Select PG1
IS31FL3733_write_register(bus, addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM);
// Set PWM on all LEDs to 0
// No need to setup Breath registers to PWM as that is the default.
for (int i = 0x00; i <= 0xBF; i++) {
IS31FL3733_write_register(bus, addr, i, 0x00);
}
// Unlock the command register.
IS31FL3733_write_register(bus, addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
// Select PG3
IS31FL3733_write_register(bus, addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION);
// Set global current to maximum.
IS31FL3733_write_register(bus, addr, ISSI_REG_GLOBALCURRENT, 0xFF);
// Disable software shutdown.
IS31FL3733_write_register(bus, addr, ISSI_REG_CONFIGURATION, (sync << 6) | 0x01);
// Wait 10ms to ensure the device has woken up.
wait_ms(10);
}
void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
if (index >= 0 && index < DRIVER_LED_TOTAL) {
is31_led led = g_is31_leds[index];
g_pwm_buffer[led.driver][led.r] = red;
g_pwm_buffer[led.driver][led.g] = green;
g_pwm_buffer[led.driver][led.b] = blue;
g_pwm_buffer_update_required[led.driver] = true;
}
}
void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
IS31FL3733_set_color(i, red, green, blue);
}
}
void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
is31_led led = g_is31_leds[index];
uint8_t control_register_r = led.r / 8;
uint8_t control_register_g = led.g / 8;
uint8_t control_register_b = led.b / 8;
uint8_t bit_r = led.r % 8;
uint8_t bit_g = led.g % 8;
uint8_t bit_b = led.b % 8;
if (red) {
g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
} else {
g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
}
if (green) {
g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
} else {
g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
}
if (blue) {
g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
} else {
g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
}
g_led_control_registers_update_required[led.driver] = true;
}
void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index) {
if (g_pwm_buffer_update_required[index]) {
// Firstly we need to unlock the command register and select PG1.
IS31FL3733_write_register(index, addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
IS31FL3733_write_register(index, addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM);
// If any of the transactions fail we risk writing dirty PG0,
// refresh page 0 just in case.
if (!IS31FL3733_write_pwm_buffer(index, addr, g_pwm_buffer[index])) {
g_led_control_registers_update_required[index] = true;
}
}
g_pwm_buffer_update_required[index] = false;
}
void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index) {
if (g_led_control_registers_update_required[index]) {
// Firstly we need to unlock the command register and select PG0
IS31FL3733_write_register(index, addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
IS31FL3733_write_register(index, addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL);
for (int i = 0; i < 24; i++) {
IS31FL3733_write_register(index, addr, i, g_led_control_registers[index][i]);
}
}
g_led_control_registers_update_required[index] = false;
}
#endif

View File

@ -0,0 +1,251 @@
/* Copyright 2017 Jason Williams
* Copyright 2018 Jack Humbert
* Copyright 2018 Yiancar
*
* 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/>.
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
typedef struct is31_led {
uint8_t driver : 2;
uint8_t r;
uint8_t g;
uint8_t b;
} __attribute__((packed)) is31_led;
extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
void IS31FL3733_init(uint8_t bus, uint8_t addr, uint8_t sync);
bool IS31FL3733_write_register(uint8_t index, uint8_t addr, uint8_t reg, uint8_t data);
bool IS31FL3733_write_pwm_buffer(uint8_t index, uint8_t addr, uint8_t *pwm_buffer);
void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue);
// This should not be called from an interrupt
// (eg. from a timer interrupt).
// Call this while idle (in between matrix scans).
// If the buffer is dirty, it will update the driver with the buffer.
void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index); // index is the driver index
void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index);
#define A_1 0x00
#define A_2 0x01
#define A_3 0x02
#define A_4 0x03
#define A_5 0x04
#define A_6 0x05
#define A_7 0x06
#define A_8 0x07
#define A_9 0x08
#define A_10 0x09
#define A_11 0x0A
#define A_12 0x0B
#define A_13 0x0C
#define A_14 0x0D
#define A_15 0x0E
#define A_16 0x0F
#define B_1 0x10
#define B_2 0x11
#define B_3 0x12
#define B_4 0x13
#define B_5 0x14
#define B_6 0x15
#define B_7 0x16
#define B_8 0x17
#define B_9 0x18
#define B_10 0x19
#define B_11 0x1A
#define B_12 0x1B
#define B_13 0x1C
#define B_14 0x1D
#define B_15 0x1E
#define B_16 0x1F
#define C_1 0x20
#define C_2 0x21
#define C_3 0x22
#define C_4 0x23
#define C_5 0x24
#define C_6 0x25
#define C_7 0x26
#define C_8 0x27
#define C_9 0x28
#define C_10 0x29
#define C_11 0x2A
#define C_12 0x2B
#define C_13 0x2C
#define C_14 0x2D
#define C_15 0x2E
#define C_16 0x2F
#define D_1 0x30
#define D_2 0x31
#define D_3 0x32
#define D_4 0x33
#define D_5 0x34
#define D_6 0x35
#define D_7 0x36
#define D_8 0x37
#define D_9 0x38
#define D_10 0x39
#define D_11 0x3A
#define D_12 0x3B
#define D_13 0x3C
#define D_14 0x3D
#define D_15 0x3E
#define D_16 0x3F
#define E_1 0x40
#define E_2 0x41
#define E_3 0x42
#define E_4 0x43
#define E_5 0x44
#define E_6 0x45
#define E_7 0x46
#define E_8 0x47
#define E_9 0x48
#define E_10 0x49
#define E_11 0x4A
#define E_12 0x4B
#define E_13 0x4C
#define E_14 0x4D
#define E_15 0x4E
#define E_16 0x4F
#define F_1 0x50
#define F_2 0x51
#define F_3 0x52
#define F_4 0x53
#define F_5 0x54
#define F_6 0x55
#define F_7 0x56
#define F_8 0x57
#define F_9 0x58
#define F_10 0x59
#define F_11 0x5A
#define F_12 0x5B
#define F_13 0x5C
#define F_14 0x5D
#define F_15 0x5E
#define F_16 0x5F
#define G_1 0x60
#define G_2 0x61
#define G_3 0x62
#define G_4 0x63
#define G_5 0x64
#define G_6 0x65
#define G_7 0x66
#define G_8 0x67
#define G_9 0x68
#define G_10 0x69
#define G_11 0x6A
#define G_12 0x6B
#define G_13 0x6C
#define G_14 0x6D
#define G_15 0x6E
#define G_16 0x6F
#define H_1 0x70
#define H_2 0x71
#define H_3 0x72
#define H_4 0x73
#define H_5 0x74
#define H_6 0x75
#define H_7 0x76
#define H_8 0x77
#define H_9 0x78
#define H_10 0x79
#define H_11 0x7A
#define H_12 0x7B
#define H_13 0x7C
#define H_14 0x7D
#define H_15 0x7E
#define H_16 0x7F
#define I_1 0x80
#define I_2 0x81
#define I_3 0x82
#define I_4 0x83
#define I_5 0x84
#define I_6 0x85
#define I_7 0x86
#define I_8 0x87
#define I_9 0x88
#define I_10 0x89
#define I_11 0x8A
#define I_12 0x8B
#define I_13 0x8C
#define I_14 0x8D
#define I_15 0x8E
#define I_16 0x8F
#define J_1 0x90
#define J_2 0x91
#define J_3 0x92
#define J_4 0x93
#define J_5 0x94
#define J_6 0x95
#define J_7 0x96
#define J_8 0x97
#define J_9 0x98
#define J_10 0x99
#define J_11 0x9A
#define J_12 0x9B
#define J_13 0x9C
#define J_14 0x9D
#define J_15 0x9E
#define J_16 0x9F
#define K_1 0xA0
#define K_2 0xA1
#define K_3 0xA2
#define K_4 0xA3
#define K_5 0xA4
#define K_6 0xA5
#define K_7 0xA6
#define K_8 0xA7
#define K_9 0xA8
#define K_10 0xA9
#define K_11 0xAA
#define K_12 0xAB
#define K_13 0xAC
#define K_14 0xAD
#define K_15 0xAE
#define K_16 0xAF
#define L_1 0xB0
#define L_2 0xB1
#define L_3 0xB2
#define L_4 0xB3
#define L_5 0xB4
#define L_6 0xB5
#define L_7 0xB6
#define L_8 0xB7
#define L_9 0xB8
#define L_10 0xB9
#define L_11 0xBA
#define L_12 0xBB
#define L_13 0xBC
#define L_14 0xBD
#define L_15 0xBE
#define L_16 0xBF

View File

@ -0,0 +1,57 @@
/* Copyright 2021 Andrew Fahmy
*
* 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 RGB_MATRIX_ENABLE
#include "rgb_matrix.h"
#include "i2c_master.h"
#include "is31fl3733-dual.h"
static void init(void) {
i2c_init(&I2CD1, I2C1_SCL_BANK, I2C1_SDA_BANK, I2C1_SCL, I2C1_SDA);
IS31FL3733_init(0, DRIVER_ADDR_1, 0);
# ifdef USE_I2C2
i2c_init(&I2CD2, I2C2_SCL_BANK, I2C2_SDA_BANK, I2C2_SCL, I2C2_SDA);
IS31FL3733_init(1, DRIVER_ADDR_2, 0);
# endif
for (int index = 0; index < DRIVER_LED_TOTAL; index++) {
bool enabled = true;
// This only caches it for later
IS31FL3733_set_led_control_register(index, enabled, enabled, enabled);
}
IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0);
# ifdef USE_I2C2
IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1);
# endif
}
static void flush(void) {
IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0);
# ifdef USE_I2C2
IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1);
# endif
}
const rgb_matrix_driver_t rgb_matrix_driver = {
.init = init,
.flush = flush,
.set_color = IS31FL3733_set_color,
.set_color_all = IS31FL3733_set_color_all,
};
#endif

View File

@ -17,7 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "k_type.h"
#ifdef RGB_MATRIX_ENABLE
#include "is31fl3733-dual.h"
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
{ 0, B_1, A_1, C_1 },
{ 0, B_2, A_2, C_2 },
@ -45,11 +50,11 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
{ 0, E_7, D_7, F_7 },
{ 0, E_8, D_8, F_8 },
{ 0, E_9, D_9, F_9 },
{ 0, E_10, D_1, F_10 },
{ 0, E_11, D_1, F_11 },
{ 0, E_12, D_1, F_12 },
{ 0, E_13, D_1, F_13 },
{ 0, E_14, D_1, F_14 },
{ 0, E_10, D_10, F_10 },
{ 0, E_11, D_11, F_11 },
{ 0, E_12, D_12, F_12 },
{ 0, E_13, D_13, F_13 },
{ 0, E_14, D_14, F_14 },
{ 0, E_15, D_15, F_15 },
{ 0, E_16, D_16, F_16 },
@ -62,11 +67,11 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
{ 0, H_7, G_7, I_7 },
{ 0, H_8, G_8, I_8 },
{ 0, H_9, G_9, I_9 },
{ 0, H_10, G_1, I_10 },
{ 0, H_11, G_1, I_11 },
{ 0, H_12, G_1, I_12 },
{ 0, H_13, G_1, I_13 },
{ 0, H_14, G_1, I_14 },
{ 0, H_10, G_10, I_10 },
{ 0, H_11, G_11, I_11 },
{ 0, H_12, G_12, I_12 },
{ 0, H_13, G_13, I_13 },
{ 0, H_14, G_14, I_14 },
{ 0, H_15, G_15, I_15 },
{ 0, H_16, G_16, I_16 },
@ -79,106 +84,123 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
{ 0, K_7, J_7, L_7 },
{ 0, K_8, J_8, L_8 },
{ 0, K_9, J_9, L_9 },
{ 0, K_10, J_1, L_10 },
{ 0, K_11, J_1, L_11 },
{ 0, K_12, J_1, L_12 },
{ 0, K_13, J_1, L_13 },
{ 0, K_14, J_1, L_14 },
{ 0, K_10, J_10, L_10 },
{ 0, K_11, J_11, L_11 },
{ 0, K_12, J_12, L_12 },
{ 0, K_13, J_13, L_13 },
{ 0, K_14, J_14, L_14 },
{ 0, K_15, J_15, L_15 },
{ 0, K_16, J_16, L_16 },
// Driver 2 is on I2C2 - currently not usable with i2c_master
//{ 1, B_1, A_1, C_1 },
//{ 1, B_2, A_2, C_2 },
//{ 1, B_3, A_3, C_3 },
//{ 1, B_4, A_4, C_4 },
//{ 1, B_5, A_5, C_5 },
//{ 1, B_6, A_6, C_6 },
//{ 1, B_7, A_7, C_7 },
//{ 1, B_8, A_8, C_8 },
//{ 1, B_9, A_9, C_9 },
//{ 1, B_10, A_10, C_10 },
//{ 1, B_11, A_11, C_11 },
//{ 1, B_12, A_12, C_12 },
//{ 1, B_13, A_13, C_13 },
//{ 1, B_14, A_14, C_14 },
//{ 1, B_15, A_15, C_15 },
//{ 1, B_16, A_16, C_16 },
{ 1, B_1, A_1, C_1 },
{ 1, B_2, A_2, C_2 },
{ 1, B_3, A_3, C_3 },
{ 1, B_4, A_4, C_4 },
{ 1, B_5, A_5, C_5 },
{ 1, B_6, A_6, C_6 },
{ 1, B_7, A_7, C_7 },
{ 1, B_8, A_8, C_8 },
{ 1, B_9, A_9, C_9 },
{ 1, B_10, A_10, C_10 },
{ 1, B_11, A_11, C_11 },
{ 1, B_12, A_12, C_12 },
{ 1, B_13, A_13, C_13 },
{ 1, B_14, A_14, C_14 },
{ 1, B_15, A_15, C_15 },
{ 1, B_16, A_16, C_16 },
//{ 1, E_1, D_1, F_1 },
//{ 1, E_2, D_2, F_2 },
//{ 1, E_3, D_3, F_3 },
//{ 1, E_4, D_4, F_4 },
//{ 1, E_5, D_5, F_5 },
//{ 1, E_6, D_6, F_6 },
//{ 1, E_7, D_7, F_7 },
//{ 1, E_8, D_8, F_8 },
//{ 1, E_9, D_9, F_9 },
//{ 1, E_10, D_1, F_10 },
//{ 1, E_11, D_1, F_11 },
//{ 1, E_12, D_1, F_12 },
//{ 1, E_13, D_1, F_13 },
//{ 1, E_14, D_1, F_14 },
//{ 1, E_15, D_15, F_15 },
//{ 1, E_16, D_16, F_16 },
{ 1, E_1, D_1, F_1 },
{ 1, E_2, D_2, F_2 },
{ 1, E_3, D_3, F_3 },
{ 1, E_4, D_4, F_4 },
{ 1, E_5, D_5, F_5 },
{ 1, E_6, D_6, F_6 },
{ 1, E_7, D_7, F_7 },
{ 1, E_8, D_8, F_8 },
{ 1, E_9, D_9, F_9 },
{ 1, E_10, D_10, F_10 },
{ 1, E_11, D_11, F_11 },
{ 1, E_12, D_12, F_12 },
{ 1, E_13, D_13, F_13 },
{ 1, E_14, D_14, F_14 },
{ 1, E_15, D_15, F_15 },
{ 1, E_16, D_16, F_16 },
//{ 1, H_1, G_1, I_1 },
//{ 1, H_2, G_2, I_2 },
//{ 1, H_3, G_3, I_3 },
//{ 1, H_4, G_4, I_4 },
//{ 1, H_5, G_5, I_5 },
//{ 1, H_6, G_6, I_6 },
//{ 1, H_7, G_7, I_7 },
//{ 1, H_8, G_8, I_8 },
//{ 1, H_9, G_9, I_9 },
//{ 1, H_10, G_1, I_10 },
//{ 1, H_11, G_1, I_11 },
//{ 1, H_12, G_1, I_12 },
//{ 1, H_13, G_1, I_13 },
//{ 1, H_14, G_1, I_14 },
//{ 1, H_15, G_15, I_15 },
//{ 1, H_16, G_16, I_16 },
{ 1, H_1, G_1, I_1 },
{ 1, H_2, G_2, I_2 },
{ 1, H_3, G_3, I_3 },
{ 1, H_4, G_4, I_4 },
{ 1, H_5, G_5, I_5 },
{ 1, H_6, G_6, I_6 },
{ 1, H_7, G_7, I_7 },
{ 1, H_8, G_8, I_8 },
{ 1, H_9, G_9, I_9 },
{ 1, H_10, G_10, I_10 },
{ 1, H_11, G_11, I_11 },
{ 1, H_12, G_12, I_12 },
{ 1, H_13, G_13, I_13 },
{ 1, H_14, G_14, I_14 },
{ 1, H_15, G_15, I_15 },
{ 1, H_16, G_16, I_16 },
//{ 1, K_1, J_1, L_1 },
//{ 1, K_2, J_2, L_2 },
//{ 1, K_3, J_3, L_3 },
//{ 1, K_4, J_4, L_4 },
//{ 1, K_5, J_5, L_5 },
//{ 1, K_6, J_6, L_6 },
//{ 1, K_7, J_7, L_7 }
{ 1, K_1, J_1, L_1 },
{ 1, K_2, J_2, L_2 },
{ 1, K_3, J_3, L_3 },
{ 1, K_4, J_4, L_4 },
{ 1, K_5, J_5, L_5 },
{ 1, K_6, J_6, L_6 },
{ 1, K_7, J_7, L_7 }
};
led_config_t g_led_config = {
{
// Key Matrix to LED Index
{ 0, 10, 20, 29, 38, 47, 57, NO_LED, NO_LED, NO_LED },
{ 1, 11, 21, NO_LED, 39, 48, 58, NO_LED, NO_LED, NO_LED },
{ 2, 12, 22, 30, 40, 49, 59, NO_LED, NO_LED, NO_LED },
{ 3, 13, 23, 31, 41, 50, 60, NO_LED, NO_LED, NO_LED },
{ 4, 14, 24, 32, 42, 51, 61, NO_LED, NO_LED, NO_LED },
{ 5, 15, 25, 33, 43, 52, NO_LED, NO_LED, NO_LED, NO_LED },
{ 6, 16, 26, 34, 44, 53, 62, NO_LED, NO_LED, NO_LED },
{ 7, 17, 27, 35, 45, 54, NO_LED, NO_LED, NO_LED, NO_LED },
{ 8, 18, 28, 36, 46, 55, 63, NO_LED, NO_LED, NO_LED },
{ 9, 19, NO_LED, 37, NO_LED, 56, NO_LED, NO_LED, NO_LED, NO_LED }
{ 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, NO_LED },
{ 29, NO_LED, 30, 31, 32, 33, 34, 35, 36, 37 },
{ 38, 39, 40, 41, 42, 43, 44, 45, 46, NO_LED },
{ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 },
{ 57, 58, 59, 60, 61, NO_LED, 62, NO_LED, 63, NO_LED },
{ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73 },
{ NO_LED, 74, NO_LED, 75, 76, 77, 78, 79, 80, 81 },
{ 82, 83, 84, 85, 86, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED }
}, {
// LED Index to Physical Position
// Key LED
{ 0, 0 }, { 26.35, 0 }, { 39.53, 0 }, { 52.71, 0 }, { 65.88, 0 }, { 79.06, 0 }, { 92.24, 0 }, { 105.41, 0 }, { 118.59, 0 }, { 131.77, 0 }, { 144.94, 0 }, { 158.12, 0 }, { 171.29, 0 }, { 197.65, 0 }, { 210.82, 0 }, { 224, 0 },
{ 0, 21.33 }, { 13.18, 21.33 }, { 26.35, 21.33 }, { 39.53, 21.33 }, { 52.71, 21.33 }, { 65.88, 21.33 }, { 79.06, 21.33 }, { 92.24, 21.33 }, { 105.41, 21.33 }, { 118.59, 21.33 }, { 131.77, 21.33 }, { 144.94, 21.33 }, { 158.12, 21.33 }, { 171.29, 21.33 }, { 197.65, 21.33 }, { 210.82, 21.33 }, { 224, 21.33 },
{ 0, 32 }, { 13.18, 32 }, { 26.35, 32 }, { 39.53, 32 }, { 52.71, 32 }, { 65.88, 32 }, { 79.06, 32 }, { 92.24, 32 }, { 105.41, 32 }, { 118.59, 32 }, { 131.77, 32 }, { 144.94, 32 }, { 158.12, 32 }, { 171.29, 32 }, { 197.65, 32 }, { 210.82, 32 }, { 224, 32 },
{ 0, 42.67 }, { 13.18, 42.67 }, { 26.35, 42.67 }, { 39.53, 42.67 }, { 52.71, 42.67 }, { 65.88, 42.67 }, { 79.06, 42.67 }, { 92.24, 42.67 }, { 105.41, 42.67 }, { 118.59, 42.67 }, { 131.77, 42.67 }, { 144.94, 42.67 }, { 171.29, 42.67 },
{ 0, 53.33 }, //{ 26.35, 53.33 }, { 39.53, 53.33 }, { 52.71, 53.33 }, { 65.88, 53.33 }, { 79.06, 53.33 }, { 92.24, 53.33 }, { 105.41, 53.33 }, { 118.59, 53.33 }, { 131.77, 53.33 }, { 144.94, 53.33 }, { 171.29, 53.33 }, { 210.82, 53.33 },
//{ 0, 64 }, { 13.18, 64 }, { 26.35, 64 }, { 79.06, 64 }, { 131.77, 64 }, { 144.94, 64 }, { 158.12, 64 }, { 171.29, 64 }, { 197.65, 64 }, { 210.82, 64 }, { 224, 64 }
{ 0, 53.33 }, { 26.35, 53.33 }, { 39.53, 53.33 }, { 52.71, 53.33 }, { 65.88, 53.33 }, { 79.06, 53.33 }, { 92.24, 53.33 }, { 105.41, 53.33 }, { 118.59, 53.33 }, { 131.77, 53.33 }, { 144.94, 53.33 }, { 171.29, 53.33 }, { 210.82, 53.33 },
{ 0, 64 }, { 13.18, 64 }, { 26.35, 64 }, { 79.06, 64 }, { 131.77, 64 }, { 144.94, 64 }, { 158.12, 64 }, { 171.29, 64 }, { 197.65, 64 }, { 210.82, 64 }, { 224, 64 },
// Underglow LED
{ 224, 64 }, { 206.77, 64 }, { 189.54, 64 }, { 172.31, 64 }, { 155.08, 64 }, { 137.85, 64 }, { 120.61, 64 }, { 103.38, 64 }, { 86.15, 64 }, { 68.92, 64 }, { 51.69, 64 }, { 34.46, 64 }, { 17.23, 64 }, { 0, 64 },
{ 0, 42.67 }, { 0, 21.33 },
{ 0, 0 }, { 17.23, 0 }, { 34.46, 0 }, { 51.69, 0 }, { 68.92, 0 }, { 86.15, 0 }, { 103.38, 0 }, { 120.61, 0 }, { 137.85, 0 }, { 155.08, 0 }, { 172.31, 0 }, { 189.54, 0 }, { 206.77, 0 }, { 224, 0 },
{ 224, 21.33 }, { 224, 42.67 }
}, {
// LED Index to Flag
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
//Key LED
1, 4, 4, 4, 4, 1, 1, 1, 1, 4, 4, 4, 4, 1, 1, 1,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 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, 1, 1,
//1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4,
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
// Underglow LED
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2,
2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
}
};
#endif

View File

@ -0,0 +1,52 @@
/* Copyright 2021 Andrew Fahmy
*
* 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/>.
*/
#pragma once
#ifdef RGB_MATRIX_ENABLE
// # define RGB_MATRIX_FRAMEBUFFER_EFFECTS
// # define RGB_MATRIX_KEYPRESSES
# define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_RAINDROPS
// # define DEBUG_MATRIX_SCAN_RATE
# define RGB_MATRIX_LED_FLUSH_LIMIT 100
// # define RGB_MATRIX_LED_PROCESS_LIMIT 2
// i2c_master defines
# define I2C_COUNT 2
# define I2C1_BANK GPIOB
# define I2C1_SCL 0 // A2 on pinout = B0
# define I2C1_SDA 1 // A2 on pinout = B1
# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define USE_I2C2
# define I2C2_BANK GPIOC
# define I2C2_SCL 10 // A2 on pinout = C10
# define I2C2_SDA 11 // A2 on pinout = C11
# define I2C2_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define I2C2_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define DRIVER_ADDR_1 0b1010000
# define DRIVER_ADDR_2 0b1010000
# define DRIVER_COUNT 2
# define DRIVER_1_LED_TOTAL 64
# define DRIVER_2_LED_TOTAL 55
# define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
#endif

View File

@ -0,0 +1,60 @@
/* Copyright 2021 Andrew Fahmy
*
* 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/>.
*/
#include QMK_KEYBOARD_H
enum layer_names {
_MAIN,
_L1
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_MAIN] = LAYOUT_tkl_ansi(
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS,
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
MO(_L1), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
KC_LCTL, _______, KC_LALT, KC_SPC, KC_RALT, MO(_L1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[_L1] = LAYOUT_tkl_ansi(
RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_TOG, RGB_MOD, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SPD, RGB_SPI, _______, RGB_HUI, RGB_SAI, RGB_VAI,
_______, KC_MPRV, KC_MPLY, KC_MNXT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_VAD,
_______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, KC_LGUI, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
void keyboard_post_init_user(void) {
// Customise these values to desired behaviour
// debug_enable=true;
// debug_matrix=true;
// debug_keyboard=true;
// debug_mouse=true;
}
#ifdef RGB_MATRIX_ENABLE
// Turn off SDB
void keyboard_pre_init_user() {
palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(GPIOB, 16);
}
#endif

View File

@ -0,0 +1 @@
RGB_MATRIX_ENABLE = yes

View File

@ -2,22 +2,31 @@
#ifdef RGB_MATRIX_ENABLE
# define RGB_MATRIX_KEYPRESSES
# define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_ALL
# define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_SOLID_COLOR
# define RGB_MATRIX_LED_FLUSH_LIMIT 100
// i2c_master defines
# define I2C_COUNT 2
# define I2C1_BANK GPIOB
# define I2C1_SCL 0 // A2 on pinout = B0
# define I2C1_SDA 1 // A2 on pinout = B1
# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
//# define I2C2_SCL 10 // A2 on pinout = C10
//# define I2C2_SDA 11 // A2 on pinout = C11
//# define I2C2_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
//# define I2C2_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define USE_I2C2
# define I2C2_BANK GPIOC
# define I2C2_SCL 10 // A2 on pinout = C10
# define I2C2_SDA 11 // A2 on pinout = C11
# define I2C2_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define I2C2_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2
# define DRIVER_ADDR_1 0b1010000
# define DRIVER_ADDR_2 0b1010001
# define DRIVER_ADDR_2 0b1010000
# define DRIVER_COUNT 2
# define DRIVER_1_LED_TOTAL 64
//# define DRIVER_2_LED_TOTAL 55
# define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL
# define DRIVER_2_LED_TOTAL 55
# define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
#endif

View File

@ -8,12 +8,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_tkl_ansi(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_TOG, RGB_MOD, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, RGB_SAI, RGB_VAI,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SPD, RGB_SPI, _______, RGB_HUI, RGB_SAI, RGB_VAI,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_VAD,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,

View File

@ -2,4 +2,6 @@
This is an experimental keymap adding support for RGB Matrix on the K-Type.
The board has two IS31FL3733 LED controllers, but they are each on different I2C buses, which QMK's `i2c_master` implementation currently does not support. As a result, all the keys after the left shift will not be lit.
The keyboard should now support full RGB lightings. The lighting animations are running at 10 fps for performance reasons.
You can configure this by changing the `RGB_MATRIX_LED_FLUSH_LIMIT` inside the `config.h` file to a lower value.
For example `RGB_MATRIX_LED_FLUSH_LIMIT 16` would mean that the animations run every 16 ms or at 60 fps.

View File

@ -51,4 +51,7 @@
#define KINETIS_I2C_USE_I2C0 TRUE
#define KINETIS_I2C_I2C0_PRIORITY 4
#define KINETIS_I2C_USE_I2C1 TRUE
#define KINETIS_I2C_I2C0_PRIORITY 4
#endif /* _MCUCONF_H_ */

View File

@ -27,7 +27,11 @@ RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output
RGB_MATRIX_ENABLE = no
RGB_MATRIX_DRIVER = IS31FL3733
RGB_MATRIX_DRIVER = custom
SRC += k_type-rgbdriver.c
QUANTUM_LIB_SRC += i2c_master.c is31fl3733-dual.c
LAYOUTS = tkl_ansi