From fa4052c26e33b42b65521fd5ba9f94a3a778b275 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 8 Apr 2019 19:57:43 -0400 Subject: [PATCH] Adds the Planck EZ, 3737 RGB, fixes out-of-tune notes (#5532) * RGB Matrix overhaul Breakout of animations to separate files Integration of optimized int based math lib Overhaul of rgb_matrix.c and animations for performance * Updating effect function api for future extensions * Combined the keypresses || keyreleases define checks into a single define so I stop forgetting it where necessary * Moving define RGB_MATRIX_KEYREACTIVE_ENABLED earlier in the include chain * Adds the Planck EZ, 3737 RGB, fixes out-of-tune notes * fix bug in quantum/rgb_matrix_drivers.c Co-Authored-By: jackhumbert * update command setting to the correct default * correct rgb config * remove commented-out lines * update docs for the 3737 * Update docs/feature_rgb_matrix.md Co-Authored-By: jackhumbert --- common_features.mk | 14 +- docs/feature_rgb_matrix.md | 4 +- drivers/issi/is31fl3737.c | 252 +++++++++++++++++++++++++++++++++++ drivers/issi/is31fl3737.h | 207 ++++++++++++++++++++++++++++ keyboards/planck/ez/config.h | 141 ++++++++++++++++++++ keyboards/planck/ez/ez.c | 175 ++++++++++++++++++++++++ keyboards/planck/ez/ez.h | 107 +++++++++++++++ keyboards/planck/ez/rules.mk | 24 ++++ keyboards/planck/planck.h | 6 +- quantum/audio/audio_arm.c | 6 +- quantum/rgb_matrix.h | 4 +- quantum/rgb_matrix_drivers.c | 28 +++- quantum/stm32/halconf.h | 2 +- quantum/stm32/mcuconf.h | 2 +- 14 files changed, 956 insertions(+), 16 deletions(-) create mode 100644 drivers/issi/is31fl3737.c create mode 100644 drivers/issi/is31fl3737.h create mode 100644 keyboards/planck/ez/config.h create mode 100644 keyboards/planck/ez/ez.c create mode 100644 keyboards/planck/ez/ez.h create mode 100644 keyboards/planck/ez/rules.mk diff --git a/common_features.mk b/common_features.mk index 046f94d1db..c3b6fa9168 100644 --- a/common_features.mk +++ b/common_features.mk @@ -114,7 +114,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) endif endif -VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 custom +VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 IS31FL3737 custom LED_MATRIX_ENABLE ?= no ifneq ($(strip $(LED_MATRIX_ENABLE)), no) @@ -135,6 +135,7 @@ ifeq ($(strip $(LED_MATRIX_ENABLE)), IS31FL3731) endif RGB_MATRIX_ENABLE ?= no + ifneq ($(strip $(RGB_MATRIX_ENABLE)), no) ifeq ($(filter $(RGB_MATRIX_ENABLE),$(VALID_MATRIX_TYPES)),) $(error RGB_MATRIX_ENABLE="$(RGB_MATRIX_ENABLE)" is not a valid matrix type) @@ -151,19 +152,26 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) endif ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3731) - OPT_DEFS += -DIS31FL3731 + OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE COMMON_VPATH += $(DRIVER_PATH)/issi SRC += is31fl3731.c SRC += i2c_master.c endif ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3733) - OPT_DEFS += -DIS31FL3733 + OPT_DEFS += -DIS31FL3733 -DSTM32_I2C -DHAL_USE_I2C=TRUE COMMON_VPATH += $(DRIVER_PATH)/issi SRC += is31fl3733.c SRC += i2c_master.c endif +ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3737) + OPT_DEFS += -DIS31FL3737 -DSTM32_I2C -DHAL_USE_I2C=TRUE + COMMON_VPATH += $(DRIVER_PATH)/issi + SRC += is31fl3737.c + SRC += i2c_master.c +endif + ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) OPT_DEFS += -DTAP_DANCE_ENABLE SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index ec12189545..36d9d01136 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -52,7 +52,9 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now). -### IS31FL3733 +### IS31FL3733/IS31FL3737 + +!> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`. There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`: diff --git a/drivers/issi/is31fl3737.c b/drivers/issi/is31fl3737.c new file mode 100644 index 0000000000..6491049274 --- /dev/null +++ b/drivers/issi/is31fl3737.c @@ -0,0 +1,252 @@ +/* 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 . + */ + +#ifdef __AVR__ +#include +#include +#include +#else +#include "wait.h" +#endif + +#include +#include "i2c_master.h" +#include "progmem.h" +#include "rgb_matrix.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 IS31FL3737 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 IS31FL3737_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 = false; + +uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 } }; +bool g_led_control_registers_update_required = false; + +void IS31FL3737_write_register( uint8_t addr, uint8_t reg, uint8_t data ) +{ + 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(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) + break; + } + #else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); + #endif +} + +void IS31FL3737_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) +{ + // assumes PG1 is already selected + + // 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(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) + break; + } + #else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); + #endif + } +} + +void IS31FL3737_init( uint8_t addr ) +{ + // 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. + + // Unlock the command register. + IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + + // Select PG0 + IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); + // Turn off all LEDs. + for ( int i = 0x00; i <= 0x17; i++ ) + { + IS31FL3737_write_register( addr, i, 0x00 ); + } + + // Unlock the command register. + IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + + // Select PG1 + IS31FL3737_write_register( 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++ ) + { + IS31FL3737_write_register( addr, i, 0x00 ); + } + + // Unlock the command register. + IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + + // Select PG3 + IS31FL3737_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION ); + // Set global current to maximum. + IS31FL3737_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF ); + // Disable software shutdown. + IS31FL3737_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 ); + + // Wait 10ms to ensure the device has woken up. + #ifdef __AVR__ + _delay_ms( 10 ); + #else + wait_ms(10); + #endif +} + +void IS31FL3737_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 = true; + } +} + +void IS31FL3737_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) +{ + for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) + { + IS31FL3737_set_color( i, red, green, blue ); + } +} + +void IS31FL3737_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 = true; + +} + +void IS31FL3737_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ) +{ + if ( g_pwm_buffer_update_required ) + { + // Firstly we need to unlock the command register and select PG1 + IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); + + IS31FL3737_write_pwm_buffer( addr1, g_pwm_buffer[0] ); + //IS31FL3737_write_pwm_buffer( addr2, g_pwm_buffer[1] ); + } + g_pwm_buffer_update_required = false; +} + +void IS31FL3737_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) +{ + if ( g_led_control_registers_update_required ) + { + // Firstly we need to unlock the command register and select PG0 + IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + IS31FL3737_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); + for ( int i=0; i<24; i++ ) + { + IS31FL3737_write_register(addr1, i, g_led_control_registers[0][i] ); + //IS31FL3737_write_register(addr2, i, g_led_control_registers[1][i] ); + } + } +} diff --git a/drivers/issi/is31fl3737.h b/drivers/issi/is31fl3737.h new file mode 100644 index 0000000000..69c4b9b538 --- /dev/null +++ b/drivers/issi/is31fl3737.h @@ -0,0 +1,207 @@ +/* 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 . + */ + + +#ifndef IS31FL3737_DRIVER_H +#define IS31FL3737_DRIVER_H + +#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 IS31FL3737_init( uint8_t addr ); +void IS31FL3737_write_register( uint8_t addr, uint8_t reg, uint8_t data ); +void IS31FL3737_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); + +void IS31FL3737_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); +void IS31FL3737_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); + +void IS31FL3737_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 IS31FL3737_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ); +void IS31FL3737_update_led_control_registers( uint8_t addr1, uint8_t addr2 ); + +#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 0x08 +#define A_8 0x09 +#define A_9 0x0A +#define A_10 0x0B +#define A_11 0x0C +#define A_12 0x0D + +#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 0x18 +#define B_8 0x19 +#define B_9 0x1A +#define B_10 0x1B +#define B_11 0x1C +#define B_12 0x1D + +#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 0x28 +#define C_8 0x29 +#define C_9 0x2A +#define C_10 0x2B +#define C_11 0x2C +#define C_12 0x2D + +#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 0x38 +#define D_8 0x39 +#define D_9 0x3A +#define D_10 0x3B +#define D_11 0x3C +#define D_12 0x3D + +#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 0x48 +#define E_8 0x49 +#define E_9 0x4A +#define E_10 0x4B +#define E_11 0x4C +#define E_12 0x4D + +#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 0x58 +#define F_8 0x59 +#define F_9 0x5A +#define F_10 0x5B +#define F_11 0x5C +#define F_12 0x5D + +#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 0x68 +#define G_8 0x69 +#define G_9 0x6A +#define G_10 0x6B +#define G_11 0x6C +#define G_12 0x6D + +#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 0x78 +#define H_8 0x79 +#define H_9 0x7A +#define H_10 0x7B +#define H_11 0x7C +#define H_12 0x7D + +#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 0x88 +#define I_8 0x89 +#define I_9 0x8A +#define I_10 0x8B +#define I_11 0x8C +#define I_12 0x8D + +#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 0x98 +#define J_8 0x99 +#define J_9 0x9A +#define J_10 0x9B +#define J_11 0x9C +#define J_12 0x9D + +#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 0xA8 +#define K_8 0xA9 +#define K_9 0xAA +#define K_10 0xAB +#define K_11 0xAC +#define K_12 0xAD + +#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 0xB8 +#define L_8 0xB9 +#define L_9 0xBA +#define L_10 0xBB +#define L_11 0xBC +#define L_12 0xBD + +#endif // IS31FL3737_DRIVER_H diff --git a/keyboards/planck/ez/config.h b/keyboards/planck/ez/config.h new file mode 100644 index 0000000000..c449d17192 --- /dev/null +++ b/keyboards/planck/ez/config.h @@ -0,0 +1,141 @@ +/* + * Copyright 2018 Jack Humbert + * + * 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 + +/* USB Device descriptor parameter */ +#define DEVICE_VER 0x0000 + +#undef MATRIX_ROWS +#undef MATRIX_COLS +/* key matrix size */ +#define MATRIX_ROWS 8 +#define MATRIX_COLS 6 + +/* + * Keyboard Matrix Assignments + * + * Change this to how you wired your keyboard + * COLS: AVR pins used for columns, left to right + * ROWS: AVR pins used for rows, top to bottom + * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) + * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) + * +*/ + +#undef MATRIX_ROW_PINS +#undef MATRIX_COL_PINS + +#define MATRIX_ROW_PINS { A10, A9, A8, B15, C13, C14, C15, A2 } +#define MATRIX_COL_PINS { B11, B10, B2, B1, A7, B0 } + +#define NUMBER_OF_ENCODERS 1 +#define ENCODERS_PAD_A { B12 } +#define ENCODERS_PAD_B { B13 } + +#define MUSIC_MAP +#undef AUDIO_VOICES +#undef C6_AUDIO + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 6 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +//#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +//#define LOCKING_RESYNC_ENABLE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +/* + * MIDI options + */ + +/* Prevent use of disabled MIDI features in the keymap */ +//#define MIDI_ENABLE_STRICT 1 + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ +//#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ +//#define MIDI_TONE_KEYCODE_OCTAVES 1 + +// #define WS2812_LED_N 2 +// #define RGBLED_NUM WS2812_LED_N +// #define WS2812_TIM_N 2 +// #define WS2812_TIM_CH 2 +// #define PORT_WS2812 GPIOA +// #define PIN_WS2812 1 +// #define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA stream for TIMx_UP (look up in reference manual under DMA Channel selection) +//#define WS2812_DMA_CHANNEL 7 // DMA channel for TIMx_UP +//#define WS2812_EXTERNAL_PULLUP + +#define DRIVER_ADDR_1 0b1010000 +#define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons. + +#define DRIVER_COUNT 1 +#define DRIVER_1_LED_TOTAL 47 +#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + +#define RGB_MATRIX_KEYPRESSES diff --git a/keyboards/planck/ez/ez.c b/keyboards/planck/ez/ez.c new file mode 100644 index 0000000000..b859af6c15 --- /dev/null +++ b/keyboards/planck/ez/ez.c @@ -0,0 +1,175 @@ +/* Copyright 2018 Jack Humbert + * + * 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 "ez.h" + +const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +/* Refer to IS31 manual for these locations + * driver + * | R location + * | | G location + * | | | B location + * | | | | */ + {0, A_12, B_12, C_12}, + {0, A_11, B_11, C_11}, + {0, A_10, B_10, C_10}, + {0, A_9, B_9, C_9}, + {0, A_8, B_8, C_8}, + {0, A_7, B_7, C_7}, + + {0, G_12, H_12, I_12}, + {0, G_11, H_11, I_11}, + {0, G_10, H_10, I_10}, + {0, G_9, H_9, I_9}, + {0, G_8, H_8, I_8}, + {0, G_7, H_7, I_7}, + + {0, A_6, B_6, C_6}, + {0, A_5, B_5, C_5}, + {0, A_4, B_4, C_4}, + {0, A_3, B_3, C_3}, + {0, A_2, B_2, C_2}, + {0, A_1, B_1, C_1}, + + {0, G_6, H_6, I_6}, + {0, G_5, H_5, I_5}, + {0, G_4, H_4, I_4}, + {0, G_3, H_3, I_3}, + {0, G_2, H_2, I_2}, + {0, G_1, H_1, I_1}, + + {0, D_12, E_12, F_12}, + {0, D_11, E_11, F_11}, + {0, D_10, E_10, F_10}, + {0, D_9, E_9, F_9}, + {0, D_8, E_8, F_8}, + {0, D_7, E_7, F_7}, + + {0, J_12, K_12, L_12}, + {0, J_11, K_11, L_11}, + {0, J_10, K_10, L_10}, + {0, J_9, K_9, L_9}, + {0, J_8, K_8, L_8}, + {0, J_7, K_7, L_7}, + + {0, D_6, E_6, F_6}, + {0, D_5, E_5, F_5}, + {0, D_4, E_4, F_4}, + {0, D_3, E_3, F_3}, + {0, D_2, E_2, F_2}, + {0, D_1, E_1, F_1}, + + {0, J_6, K_6, L_6}, + {0, J_5, K_5, L_5}, + {0, J_4, K_4, L_4}, + {0, J_3, K_3, L_3}, + {0, J_2, K_2, L_2}, + +}; + +const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = { + + /*{row | col << 4} + | {x=0..224, y=0..64} + | | modifier + | | | */ + {{0|(0<<4)}, {20.36*0, 21.33*0}, 1}, + {{0|(1<<4)}, {20.36*1, 21.33*0}, 0}, + {{0|(2<<4)}, {20.36*2, 21.33*0}, 0}, + {{0|(3<<4)}, {20.36*3, 21.33*0}, 0}, + {{0|(4<<4)}, {20.36*4, 21.33*0}, 0}, + {{0|(5<<4)}, {20.36*5, 21.33*0}, 0}, + {{4|(0<<4)}, {20.36*6, 21.33*0}, 0}, + {{4|(1<<4)}, {20.36*7, 21.33*0}, 0}, + {{4|(2<<4)}, {20.36*8, 21.33*0}, 0}, + {{4|(3<<4)}, {20.36*9, 21.33*0}, 0}, + {{4|(4<<4)}, {20.36*10,21.33*0}, 0}, + {{4|(5<<4)}, {20.36*11,21.33*0}, 1}, + + {{1|(0<<4)}, {20.36*0, 21.33*1}, 1}, + {{1|(1<<4)}, {20.36*1, 21.33*1}, 0}, + {{1|(2<<4)}, {20.36*2, 21.33*1}, 0}, + {{1|(3<<4)}, {20.36*3, 21.33*1}, 0}, + {{1|(4<<4)}, {20.36*4, 21.33*1}, 0}, + {{1|(5<<4)}, {20.36*5, 21.33*1}, 0}, + {{5|(0<<4)}, {20.36*6, 21.33*1}, 0}, + {{5|(1<<4)}, {20.36*7, 21.33*1}, 0}, + {{5|(2<<4)}, {20.36*8, 21.33*1}, 0}, + {{5|(3<<4)}, {20.36*9, 21.33*1}, 0}, + {{5|(4<<4)}, {20.36*10,21.33*1}, 0}, + {{5|(5<<4)}, {20.36*11,21.33*1}, 1}, + + {{2|(0<<4)}, {20.36*0, 21.33*2}, 1}, + {{2|(1<<4)}, {20.36*1, 21.33*2}, 0}, + {{2|(2<<4)}, {20.36*2, 21.33*2}, 0}, + {{2|(3<<4)}, {20.36*3, 21.33*2}, 0}, + {{2|(4<<4)}, {20.36*4, 21.33*2}, 0}, + {{2|(5<<4)}, {20.36*5, 21.33*2}, 0}, + {{6|(0<<4)}, {20.36*6, 21.33*2}, 0}, + {{6|(1<<4)}, {20.36*7, 21.33*2}, 0}, + {{6|(2<<4)}, {20.36*8, 21.33*2}, 0}, + {{6|(3<<4)}, {20.36*9, 21.33*2}, 0}, + {{6|(4<<4)}, {20.36*10,21.33*2}, 0}, + {{6|(5<<4)}, {20.36*11,21.33*2}, 1}, + + {{3|(0<<4)}, {20.36*0, 21.33*3}, 1}, + {{3|(1<<4)}, {20.36*1, 21.33*3}, 1}, + {{3|(2<<4)}, {20.36*2, 21.33*3}, 1}, + {{7|(3<<4)}, {20.36*3, 21.33*3}, 1}, + {{7|(4<<4)}, {20.36*4, 21.33*3}, 1}, + {{7|(5<<4)}, {20.36*5.5,21.33*3}, 0}, + {{7|(0<<4)}, {20.36*7, 21.33*3}, 1}, + {{7|(1<<4)}, {20.36*8, 21.33*3}, 1}, + {{7|(2<<4)}, {20.36*9, 21.33*3}, 1}, + {{3|(3<<4)}, {20.36*10,21.33*3}, 1}, + {{3|(4<<4)}, {20.36*11,21.33*3}, 1} +}; + +void matrix_init_kb(void) { + matrix_init_user(); + + palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL); + + palClearPad(GPIOB, 8); + palClearPad(GPIOB, 9); +} + +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +uint32_t layer_state_set_kb(uint32_t state) { + + palClearPad(GPIOB, 8); + palClearPad(GPIOB, 9); + state = layer_state_set_user(state); + uint8_t layer = biton32(state); + switch (layer) { + case 3: + palSetPad(GPIOB, 9); + break; + case 4: + palSetPad(GPIOB, 8); + break; + case 6: + palSetPad(GPIOB, 9); + palSetPad(GPIOB, 8); + break; + default: + break; + } + return state; +} diff --git a/keyboards/planck/ez/ez.h b/keyboards/planck/ez/ez.h new file mode 100644 index 0000000000..a3ca2b6ece --- /dev/null +++ b/keyboards/planck/ez/ez.h @@ -0,0 +1,107 @@ +/* Copyright 2018 Jack Humbert + * + * 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 "planck.h" + +#define LAYOUT_planck_1x2uC( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ + k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a \ +) \ +{ \ + { k00, k01, k02, k03, k04, k05 }, \ + { k10, k11, k12, k13, k14, k15 }, \ + { k20, k21, k22, k23, k24, k25 }, \ + { k30, k31, k32, k39, k3a, k3b }, \ + { k06, k07, k08, k09, k0a, k0b }, \ + { k16, k17, k18, k19, k1a, k1b }, \ + { k26, k27, k28, k29, k2a, k2b }, \ + { k36, k37, k38, k33, k34, k35 } \ +} + +#define LAYOUT_planck_1x2uR( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ + k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a \ +) \ +{ \ + { k00, k01, k02, k03, k04, k05 }, \ + { k10, k11, k12, k13, k14, k15 }, \ + { k20, k21, k22, k23, k24, k25 }, \ + { k30, k31, k32, k39, k3a, k3b }, \ + { k06, k07, k08, k09, k0a, k0b }, \ + { k16, k17, k18, k19, k1a, k1b }, \ + { k26, k27, k28, k29, k2a, k2b }, \ + { k36, k37, k38, k33, k34, k35 } \ +} + +#define LAYOUT_planck_1x2uL( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ + k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a \ +) \ +{ \ + { k00, k01, k02, k03, k04, k05 }, \ + { k10, k11, k12, k13, k14, k15 }, \ + { k20, k21, k22, k23, k24, k25 }, \ + { k30, k31, k32, k39, k3a, k3b }, \ + { k06, k07, k08, k09, k0a, k0b }, \ + { k16, k17, k18, k19, k1a, k1b }, \ + { k26, k27, k28, k29, k2a, k2b }, \ + { k36, k37, k38, k33, k34, k35 } \ +} + +#define LAYOUT_planck_2x2u( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ + k30, k31, k32, k33, k34, k36, k37, k38, k39, k3a \ +) \ +{ \ + { k00, k01, k02, k03, k04, k05 }, \ + { k10, k11, k12, k13, k14, k15 }, \ + { k20, k21, k22, k23, k24, k25 }, \ + { k30, k31, k32, k39, k3a, k3b }, \ + { k06, k07, k08, k09, k0a, k0b }, \ + { k16, k17, k18, k19, k1a, k1b }, \ + { k26, k27, k28, k29, k2a, k2b }, \ + { k36, k37, k38, k33, k34, k35 } \ +} + +#define LAYOUT_planck_grid( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ + k30, k31, k32, k33, k34, k35, KC_NO, k36, k37, k38, k39, k3a \ +) \ +{ \ + { k00, k01, k02, k03, k04, k05 }, \ + { k10, k11, k12, k13, k14, k15 }, \ + { k20, k21, k22, k23, k24, k25 }, \ + { k30, k31, k32, k39, k3a, KC_NO }, \ + { k06, k07, k08, k09, k0a, k0b }, \ + { k16, k17, k18, k19, k1a, k1b }, \ + { k26, k27, k28, k29, k2a, k2b }, \ + { k36, k37, k38, k33, k34, k35 } \ +} + +#define KEYMAP LAYOUT_planck_grid +#define LAYOUT_ortho_4x12 LAYOUT_planck_grid +#define KC_LAYOUT_ortho_4x12 KC_KEYMAP diff --git a/keyboards/planck/ez/rules.mk b/keyboards/planck/ez/rules.mk new file mode 100644 index 0000000000..c6fb52d2b5 --- /dev/null +++ b/keyboards/planck/ez/rules.mk @@ -0,0 +1,24 @@ +# project specific files +LAYOUTS += ortho_4x12 + +# Cortex version +MCU = STM32F303 + +# Build Options +# comment out to disable the options. +# +BACKLIGHT_ENABLE = no +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration +## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +NKRO_ENABLE = yes # USB Nkey Rollover +CUSTOM_MATRIX = no # Custom matrix file +AUDIO_ENABLE = yes +RGBLIGHT_ENABLE = no +# SERIAL_LINK_ENABLE = yes +ENCODER_ENABLE = yes +RGB_MATRIX_ENABLE = IS31FL3737 diff --git a/keyboards/planck/planck.h b/keyboards/planck/planck.h index d908d80ec4..4bc5e9c3f2 100644 --- a/keyboards/planck/planck.h +++ b/keyboards/planck/planck.h @@ -5,6 +5,10 @@ #define encoder_update(clockwise) encoder_update_user(uint8_t index, clockwise) +#ifdef KEYBOARD_planck_ez + #include "ez.h" +#endif + #ifdef __AVR__ #define LAYOUT_planck_mit( \ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ @@ -50,7 +54,7 @@ #define LAYOUT_ortho_4x12 LAYOUT_planck_grid #define KC_LAYOUT_ortho_4x12 KC_KEYMAP -#else +#elif KEYBOARD_planck_rev6 #define LAYOUT_planck_1x2uC( \ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c index 6760015ef4..de0cd15c58 100644 --- a/quantum/audio/audio_arm.c +++ b/quantum/audio/audio_arm.c @@ -79,7 +79,7 @@ float startup_song[][2] = STARTUP_SONG; static void gpt_cb8(GPTDriver *gptp); -#define DAC_BUFFER_SIZE 720 +#define DAC_BUFFER_SIZE 100 #ifndef DAC_SAMPLE_MAX #define DAC_SAMPLE_MAX 65535U #endif @@ -98,8 +98,8 @@ static void gpt_cb8(GPTDriver *gptp); RESTART_CHANNEL_1() #define UPDATE_CHANNEL_2_FREQ(freq) gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \ RESTART_CHANNEL_2() -#define GET_CHANNEL_1_FREQ gpt6cfg1.frequency -#define GET_CHANNEL_2_FREQ gpt7cfg1.frequency +#define GET_CHANNEL_1_FREQ (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE) +#define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE) /* diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h index 855ea03230..0e193dcb2f 100644 --- a/quantum/rgb_matrix.h +++ b/quantum/rgb_matrix.h @@ -28,7 +28,9 @@ #ifdef IS31FL3731 #include "is31fl3731.h" #elif defined (IS31FL3733) - #include "is31fl3733.h" + #include "is31fl3733.h" +#elif defined (IS31FL3737) + #include "is31fl3737.h" #endif #ifndef RGB_MATRIX_LED_FLUSH_LIMIT diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index 70b80293dd..3b7d58483a 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -23,7 +23,7 @@ * be here if shared between boards. */ -#if defined(IS31FL3731) || defined(IS31FL3733) +#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) #include "i2c_master.h" @@ -33,23 +33,29 @@ static void init( void ) #ifdef IS31FL3731 IS31FL3731_init( DRIVER_ADDR_1 ); IS31FL3731_init( DRIVER_ADDR_2 ); -#else +#elif defined(IS31FL3733) IS31FL3733_init( DRIVER_ADDR_1 ); +#else + IS31FL3737_init( DRIVER_ADDR_1 ); #endif for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) { bool enabled = true; // This only caches it for later #ifdef IS31FL3731 IS31FL3731_set_led_control_register( index, enabled, enabled, enabled ); -#else +#elif defined(IS31FL3733) IS31FL3733_set_led_control_register( index, enabled, enabled, enabled ); +#else + IS31FL3737_set_led_control_register( index, enabled, enabled, enabled ); #endif } // This actually updates the LED drivers #ifdef IS31FL3731 IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); -#else +#elif defined(IS31FL3733) IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +#else + IS31FL3737_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); #endif } @@ -65,7 +71,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color = IS31FL3731_set_color, .set_color_all = IS31FL3731_set_color_all, }; -#else +#elif defined(IS31FL3733) static void flush( void ) { IS31FL3733_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); @@ -77,6 +83,18 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color = IS31FL3733_set_color, .set_color_all = IS31FL3733_set_color_all, }; +#else +static void flush( void ) +{ + IS31FL3737_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); +} + +const rgb_matrix_driver_t rgb_matrix_driver = { + .init = init, + .flush = flush, + .set_color = IS31FL3737_set_color, + .set_color_all = IS31FL3737_set_color_all, +}; #endif #endif diff --git a/quantum/stm32/halconf.h b/quantum/stm32/halconf.h index 8fe8e0c6f5..c3e0cbb728 100644 --- a/quantum/stm32/halconf.h +++ b/quantum/stm32/halconf.h @@ -76,7 +76,7 @@ * @brief Enables the I2C subsystem. */ #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C FALSE +#define HAL_USE_I2C TRUE #endif /** diff --git a/quantum/stm32/mcuconf.h b/quantum/stm32/mcuconf.h index 7c3c6e570c..36f8ca2252 100644 --- a/quantum/stm32/mcuconf.h +++ b/quantum/stm32/mcuconf.h @@ -154,7 +154,7 @@ /* * I2C driver system settings. */ -#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C1 TRUE #define STM32_I2C_USE_I2C2 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 10