@ -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 <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifdef __AVR__ | |||
#include <avr/interrupt.h> | |||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
#else | |||
#include "wait.h" | |||
#endif | |||
#include <string.h> | |||
#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] ); | |||
} | |||
} | |||
} |
@ -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 <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef IS31FL3737_DRIVER_H | |||
#define IS31FL3737_DRIVER_H | |||
#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 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 |
@ -0,0 +1,144 @@ | |||
/* | |||
* Copyright 2018 Jack Humbert <jack.humb@gmail.com> | |||
* | |||
* 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 | |||
/* 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 | |||
/* key combination for magic key command */ | |||
#define IS_COMMAND() ( \ | |||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ | |||
) | |||
/* | |||
* 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 |
@ -0,0 +1,175 @@ | |||
/* Copyright 2018 Jack Humbert <jack.humb@gmail.com> | |||
* | |||
* 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 "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}, | |||
{{0|(6<<4)}, {20.36*6, 21.33*0}, 0}, | |||
{{0|(7<<4)}, {20.36*7, 21.33*0}, 0}, | |||
{{0|(8<<4)}, {20.36*8, 21.33*0}, 0}, | |||
{{0|(9<<4)}, {20.36*9, 21.33*0}, 0}, | |||
{{0|(10<<4)}, {20.36*10,21.33*0}, 0}, | |||
{{0|(11<<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}, | |||
{{1|(6<<4)}, {20.36*6, 21.33*1}, 0}, | |||
{{1|(7<<4)}, {20.36*7, 21.33*1}, 0}, | |||
{{1|(8<<4)}, {20.36*8, 21.33*1}, 0}, | |||
{{1|(9<<4)}, {20.36*9, 21.33*1}, 0}, | |||
{{1|(10<<4)}, {20.36*10,21.33*1}, 0}, | |||
{{1|(11<<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}, | |||
{{2|(6<<4)}, {20.36*6, 21.33*2}, 0}, | |||
{{2|(7<<4)}, {20.36*7, 21.33*2}, 0}, | |||
{{2|(8<<4)}, {20.36*8, 21.33*2}, 0}, | |||
{{2|(9<<4)}, {20.36*9, 21.33*2}, 0}, | |||
{{2|(10<<4)}, {20.36*10,21.33*2}, 0}, | |||
{{2|(11<<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}, | |||
{{3|(3<<4)}, {20.36*3, 21.33*3}, 1}, | |||
{{3|(4<<4)}, {20.36*4, 21.33*3}, 1}, | |||
{{3|(5<<4)}, {20.36*5.5,21.33*3}, 0}, | |||
{{3|(7<<4)}, {20.36*7, 21.33*3}, 1}, | |||
{{3|(8<<4)}, {20.36*8, 21.33*3}, 1}, | |||
{{3|(9<<4)}, {20.36*9, 21.33*3}, 1}, | |||
{{3|(10<<4)}, {20.36*10,21.33*3}, 1}, | |||
{{3|(11<<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; | |||
} |
@ -0,0 +1,107 @@ | |||
/* Copyright 2018 Jack Humbert <jack.humb@gmail.com> | |||
* | |||
* 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 "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 |
@ -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 |