From e6f7da403676b491ac278d5b793d18a0d114477e Mon Sep 17 00:00:00 2001 From: Andrew-Fahmy Date: Sat, 27 Feb 2021 23:38:13 -0600 Subject: [PATCH] Fixing K-type RGB lighting (#11551) * initial rgb driver fix * added underglow LEDs and fixed typo in RGB locations * removed test code * added my key maps * updated rgb keymap to work with changes * refactored my code to make it more maintainable and updated keymaps. * added GPL licence --- keyboards/k_type/i2c_master.c | 145 ++++++++++ keyboards/k_type/i2c_master.h | 127 +++++++++ keyboards/k_type/is31fl3733.c | 231 ++++++++++++++++ keyboards/k_type/is31fl3733.h | 251 ++++++++++++++++++ keyboards/k_type/k_type.c | 195 ++++++++------ .../k_type/keymaps/andrew-fahmy/config.h | 52 ++++ .../k_type/keymaps/andrew-fahmy/keymap.c | 60 +++++ .../k_type/keymaps/andrew-fahmy/rules.mk | 1 + keyboards/k_type/keymaps/rgb/config.h | 25 +- keyboards/k_type/keymaps/rgb/keymap.c | 4 +- keyboards/k_type/keymaps/rgb/readme.md | 4 +- keyboards/k_type/led.c | 53 ++++ keyboards/k_type/mcuconf.h | 3 + keyboards/k_type/rules.mk | 4 +- 14 files changed, 1055 insertions(+), 100 deletions(-) create mode 100644 keyboards/k_type/i2c_master.c create mode 100644 keyboards/k_type/i2c_master.h create mode 100644 keyboards/k_type/is31fl3733.c create mode 100644 keyboards/k_type/is31fl3733.h create mode 100644 keyboards/k_type/keymaps/andrew-fahmy/config.h create mode 100644 keyboards/k_type/keymaps/andrew-fahmy/keymap.c create mode 100644 keyboards/k_type/keymaps/andrew-fahmy/rules.mk create mode 100644 keyboards/k_type/led.c diff --git a/keyboards/k_type/i2c_master.c b/keyboards/k_type/i2c_master.c new file mode 100644 index 0000000000..72d835a604 --- /dev/null +++ b/keyboards/k_type/i2c_master.c @@ -0,0 +1,145 @@ +/* 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 . + */ + +/* 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. + */ +#include "quantum.h" +#include "i2c_master.h" +#include "print.h" +#include +#include + +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), ®addr, 1, data, length, TIME_MS2I(timeout)); + return chibios_to_qmk(&status); +} + +void i2c_stop(uint8_t index) { + if(index < I2C_COUNT) { + i2cStop(drivers[index]); + } +} diff --git a/keyboards/k_type/i2c_master.h b/keyboards/k_type/i2c_master.h new file mode 100644 index 0000000000..5a7893fae8 --- /dev/null +++ b/keyboards/k_type/i2c_master.h @@ -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 . + */ + +/* 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 +#include + +#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); diff --git a/keyboards/k_type/is31fl3733.c b/keyboards/k_type/is31fl3733.c new file mode 100644 index 0000000000..8818a622bc --- /dev/null +++ b/keyboards/k_type/is31fl3733.c @@ -0,0 +1,231 @@ +/* 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 . + */ + +#include "is31fl3733.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; +} diff --git a/keyboards/k_type/is31fl3733.h b/keyboards/k_type/is31fl3733.h new file mode 100644 index 0000000000..272bcdc417 --- /dev/null +++ b/keyboards/k_type/is31fl3733.h @@ -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 . + */ + +#pragma once + +#include +#include + +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 diff --git a/keyboards/k_type/k_type.c b/keyboards/k_type/k_type.c index ae62f0e723..567ad28430 100644 --- a/keyboards/k_type/k_type.c +++ b/keyboards/k_type/k_type.c @@ -17,6 +17,8 @@ along with this program. If not, see . #include "k_type.h" +#include "is31fl3733.h" + #ifdef RGB_MATRIX_ENABLE const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { { 0, B_1, A_1, C_1 }, @@ -45,11 +47,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 +64,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 +81,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 diff --git a/keyboards/k_type/keymaps/andrew-fahmy/config.h b/keyboards/k_type/keymaps/andrew-fahmy/config.h new file mode 100644 index 0000000000..47d20119e0 --- /dev/null +++ b/keyboards/k_type/keymaps/andrew-fahmy/config.h @@ -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 . + */ + +#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 diff --git a/keyboards/k_type/keymaps/andrew-fahmy/keymap.c b/keyboards/k_type/keymaps/andrew-fahmy/keymap.c new file mode 100644 index 0000000000..53460516cb --- /dev/null +++ b/keyboards/k_type/keymaps/andrew-fahmy/keymap.c @@ -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 . + */ + +#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( + EEP_RST, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, 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 diff --git a/keyboards/k_type/keymaps/andrew-fahmy/rules.mk b/keyboards/k_type/keymaps/andrew-fahmy/rules.mk new file mode 100644 index 0000000000..aad92997d0 --- /dev/null +++ b/keyboards/k_type/keymaps/andrew-fahmy/rules.mk @@ -0,0 +1 @@ +RGB_MATRIX_ENABLE = yes diff --git a/keyboards/k_type/keymaps/rgb/config.h b/keyboards/k_type/keymaps/rgb/config.h index 206b76f2b6..4c5d234545 100644 --- a/keyboards/k_type/keymaps/rgb/config.h +++ b/keyboards/k_type/keymaps/rgb/config.h @@ -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 diff --git a/keyboards/k_type/keymaps/rgb/keymap.c b/keyboards/k_type/keymaps/rgb/keymap.c index 4ed15e5d66..88f5eaa37b 100644 --- a/keyboards/k_type/keymaps/rgb/keymap.c +++ b/keyboards/k_type/keymaps/rgb/keymap.c @@ -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, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, diff --git a/keyboards/k_type/keymaps/rgb/readme.md b/keyboards/k_type/keymaps/rgb/readme.md index 794052c57a..330321976c 100644 --- a/keyboards/k_type/keymaps/rgb/readme.md +++ b/keyboards/k_type/keymaps/rgb/readme.md @@ -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. diff --git a/keyboards/k_type/led.c b/keyboards/k_type/led.c new file mode 100644 index 0000000000..421a7f9446 --- /dev/null +++ b/keyboards/k_type/led.c @@ -0,0 +1,53 @@ +/* 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 . + */ + +#include +#include "i2c_master.h" +#include "is31fl3733.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, +}; \ No newline at end of file diff --git a/keyboards/k_type/mcuconf.h b/keyboards/k_type/mcuconf.h index 28f3c6cdae..1d9ecf6104 100644 --- a/keyboards/k_type/mcuconf.h +++ b/keyboards/k_type/mcuconf.h @@ -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_ */ diff --git a/keyboards/k_type/rules.mk b/keyboards/k_type/rules.mk index 18b6e3c8df..8f02bede4f 100644 --- a/keyboards/k_type/rules.mk +++ b/keyboards/k_type/rules.mk @@ -27,7 +27,9 @@ 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 += i2c_master.c is31fl3733.c led.c LAYOUTS = tkl_ansi