Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
18e266f9f2 | ||
|
49f56c46e3 | ||
|
1fd3feba47 | ||
|
6a46da81cd | ||
|
1d44465dbd | ||
|
ea7b1b389d | ||
|
142661db53 | ||
|
824c80ffa8 | ||
|
cd07b64263 | ||
|
8c5ae8d6c7 | ||
|
ced0c52eac | ||
|
b3e36c734a | ||
|
33c6f74528 | ||
|
06a3b5784c | ||
|
16de11fbc5 |
@ -107,6 +107,15 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
SRC += is31fl3731.c
|
||||
SRC += TWIlib.c
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||
CIE1931_CURVE = yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
|
||||
OPT_DEFS += -DTAP_DANCE_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
|
||||
|
140
docs/feature_rgb_matrix.md
Normal file
140
docs/feature_rgb_matrix.md
Normal file
@ -0,0 +1,140 @@
|
||||
# RGB Matrix Lighting
|
||||
|
||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
|
||||
|
||||
RGB_MATRIX_ENABLE = yes
|
||||
|
||||
Configure the hardware via your `config.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:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define DRIVER_ADDR_1 0b1110100
|
||||
#define DRIVER_ADDR_2 0b1110110
|
||||
|
||||
#define DRIVER_COUNT 2
|
||||
#define DRIVER_1_LED_TOTAL 25
|
||||
#define DRIVER_2_LED_TOTAL 24
|
||||
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
|
||||
|
||||
Currently only 2 drivers are supported, but it would be trivial to support all 4 combinations.
|
||||
|
||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||
|
||||
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||
/* Refer to IS31 manual for these locations
|
||||
* driver
|
||||
* | R location
|
||||
* | | G location
|
||||
* | | | B location
|
||||
* | | | | */
|
||||
{0, C1_3, C2_3, C3_3},
|
||||
....
|
||||
}
|
||||
|
||||
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf). The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now).
|
||||
|
||||
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}, 1},
|
||||
....
|
||||
}
|
||||
|
||||
The format for the matrix position used in this array is `{row | (col << 4)}`. The `x` is between (inclusive) 0-224, and `y` is between (inclusive) 0-64. The easiest way to calculate these positions is:
|
||||
|
||||
x = 224 / ( NUMBER_OF_ROWS - 1 ) * ROW_POSITION
|
||||
y = 64 / (NUMBER_OF_COLS - 1 ) * COL_POSITION
|
||||
|
||||
Where all variables are decimels/floats.
|
||||
|
||||
`modifier` is a boolean, whether or not a certain key is considered a modifier (used in some effects).
|
||||
|
||||
## Keycodes
|
||||
|
||||
All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||
|
||||
* `RGB_TOG` - toggle
|
||||
* `RGB_MOD` - cycle through modes
|
||||
* `RGB_HUI` - increase hue
|
||||
* `RGB_HUD` - decrease hue
|
||||
* `RGB_SAI` - increase saturation
|
||||
* `RGB_SAD` - decrease saturation
|
||||
* `RGB_VAI` - increase value
|
||||
* `RGB_VAD` - decrease value
|
||||
|
||||
|
||||
* `RGB_MODE_*` keycodes will generally work, but are not currently mapped to the correct effects for the RGB Matrix system
|
||||
|
||||
## RGB Matrix Effects
|
||||
|
||||
These are the effects that are currently available:
|
||||
|
||||
enum rgb_matrix_effects {
|
||||
RGB_MATRIX_SOLID_COLOR = 1,
|
||||
RGB_MATRIX_SOLID_REACTIVE,
|
||||
RGB_MATRIX_ALPHAS_MODS,
|
||||
RGB_MATRIX_DUAL_BEACON,
|
||||
RGB_MATRIX_GRADIENT_UP_DOWN,
|
||||
RGB_MATRIX_RAINDROPS,
|
||||
RGB_MATRIX_CYCLE_ALL,
|
||||
RGB_MATRIX_CYCLE_LEFT_RIGHT,
|
||||
RGB_MATRIX_CYCLE_UP_DOWN,
|
||||
RGB_MATRIX_RAINBOW_BEACON,
|
||||
RGB_MATRIX_RAINBOW_PINWHEELS,
|
||||
RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
|
||||
RGB_MATRIX_JELLYBEAN_RAINDROPS,
|
||||
#ifdef RGB_MATRIX_KEYPRESSES
|
||||
RGB_MATRIX_SPLASH,
|
||||
RGB_MATRIX_MULTISPLASH,
|
||||
RGB_MATRIX_SOLID_SPLASH,
|
||||
RGB_MATRIX_SOLID_MULTISPLASH,
|
||||
#endif
|
||||
RGB_MATRIX_EFFECT_MAX
|
||||
};
|
||||
|
||||
## Custom layer effects
|
||||
|
||||
Custom layer effects can be done by defining this in your `<keyboard>.c`:
|
||||
|
||||
void rgb_matrix_indicators_kb(void) {
|
||||
// rgb_matrix_set_color(index, red, green, blue);
|
||||
}
|
||||
|
||||
A similar function works in the keymap as `rgb_matrix_indicators_user`.
|
||||
|
||||
## Additional `config.h` Options
|
||||
|
||||
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
|
||||
#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
|
||||
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
|
||||
#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended
|
||||
|
||||
## EEPROM storage
|
||||
|
||||
The EEPROM for it is currently shared with the RGBLIGHT system (it's generally assumed only one RGB would be used at a time), but could be configured to use its own 32bit address with:
|
||||
|
||||
#define EECONFIG_RGB_MATRIX (uint32_t *)16
|
||||
|
||||
Where `16` is an unused index from `eeconfig.h`.
|
||||
|
||||
## Suspended state
|
||||
|
||||
To use the suspend feature, add this to your `<keyboard>.c`:
|
||||
|
||||
void suspend_power_down_kb(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(true);
|
||||
}
|
||||
|
||||
void suspend_wakeup_init_kb(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(false);
|
||||
}
|
232
drivers/avr/TWIlib.c
Normal file
232
drivers/avr/TWIlib.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* TWIlib.c
|
||||
*
|
||||
* Created: 6/01/2014 10:41:33 PM
|
||||
* Author: Chris Herring
|
||||
* http://www.chrisherring.net/all/tutorial-interrupt-driven-twi-interface-for-avr-part1/
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "TWIlib.h"
|
||||
#include "util/delay.h"
|
||||
|
||||
void TWIInit()
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWIInfo.repStart = 0;
|
||||
// Set pre-scalers (no pre-scaling)
|
||||
TWSR = 0;
|
||||
// Set bit rate
|
||||
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
|
||||
// Enable TWI and interrupt
|
||||
TWCR = (1 << TWIE) | (1 << TWEN);
|
||||
}
|
||||
|
||||
uint8_t isTWIReady()
|
||||
{
|
||||
if ( (TWIInfo.mode == Ready) | (TWIInfo.mode == RepeatedStartSent) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart)
|
||||
{
|
||||
if (dataLen <= TXMAXBUFLEN)
|
||||
{
|
||||
// Wait until ready
|
||||
while (!isTWIReady()) {_delay_us(1);}
|
||||
// Set repeated start mode
|
||||
TWIInfo.repStart = repStart;
|
||||
// Copy data into the transmit buffer
|
||||
uint8_t *data = (uint8_t *)TXdata;
|
||||
for (int i = 0; i < dataLen; i++)
|
||||
{
|
||||
TWITransmitBuffer[i] = data[i];
|
||||
}
|
||||
// Copy transmit info to global variables
|
||||
TXBuffLen = dataLen;
|
||||
TXBuffIndex = 0;
|
||||
|
||||
// If a repeated start has been sent, then devices are already listening for an address
|
||||
// and another start does not need to be sent.
|
||||
if (TWIInfo.mode == RepeatedStartSent)
|
||||
{
|
||||
TWIInfo.mode = Initializing;
|
||||
TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
|
||||
TWISendTransmit(); // Send the data
|
||||
}
|
||||
else // Otherwise, just send the normal start signal to begin transmission.
|
||||
{
|
||||
TWIInfo.mode = Initializing;
|
||||
TWISendStart();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // return an error if data length is longer than buffer
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart)
|
||||
{
|
||||
// Check if number of bytes to read can fit in the RXbuffer
|
||||
if (bytesToRead < RXMAXBUFLEN)
|
||||
{
|
||||
// Reset buffer index and set RXBuffLen to the number of bytes to read
|
||||
RXBuffIndex = 0;
|
||||
RXBuffLen = bytesToRead;
|
||||
// Create the one value array for the address to be transmitted
|
||||
uint8_t TXdata[1];
|
||||
// Shift the address and AND a 1 into the read write bit (set to write mode)
|
||||
TXdata[0] = (TWIaddr << 1) | 0x01;
|
||||
// Use the TWITransmitData function to initialize the transfer and address the slave
|
||||
TWITransmitData(TXdata, 1, repStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ISR (TWI_vect)
|
||||
{
|
||||
switch (TWI_STATUS)
|
||||
{
|
||||
// ----\/ ---- MASTER TRANSMITTER OR WRITING ADDRESS ----\/ ---- //
|
||||
case TWI_MT_SLAW_ACK: // SLA+W transmitted and ACK received
|
||||
// Set mode to Master Transmitter
|
||||
TWIInfo.mode = MasterTransmitter;
|
||||
case TWI_START_SENT: // Start condition has been transmitted
|
||||
case TWI_MT_DATA_ACK: // Data byte has been transmitted, ACK received
|
||||
if (TXBuffIndex < TXBuffLen) // If there is more data to send
|
||||
{
|
||||
TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendTransmit(); // Send the data
|
||||
}
|
||||
// This transmission is complete however do not release bus yet
|
||||
else if (TWIInfo.repStart)
|
||||
{
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStart();
|
||||
}
|
||||
// All transmissions are complete, exit
|
||||
else
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStop();
|
||||
}
|
||||
break;
|
||||
|
||||
// ----\/ ---- MASTER RECEIVER ----\/ ---- //
|
||||
|
||||
case TWI_MR_SLAR_ACK: // SLA+R has been transmitted, ACK has been received
|
||||
// Switch to Master Receiver mode
|
||||
TWIInfo.mode = MasterReceiver;
|
||||
// If there is more than one byte to be read, receive data byte and return an ACK
|
||||
if (RXBuffIndex < RXBuffLen-1)
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendACK();
|
||||
}
|
||||
// Otherwise when a data byte (the only data byte) is received, return NACK
|
||||
else
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendNACK();
|
||||
}
|
||||
break;
|
||||
|
||||
case TWI_MR_DATA_ACK: // Data has been received, ACK has been transmitted.
|
||||
|
||||
/// -- HANDLE DATA BYTE --- ///
|
||||
TWIReceiveBuffer[RXBuffIndex++] = TWDR;
|
||||
// If there is more than one byte to be read, receive data byte and return an ACK
|
||||
if (RXBuffIndex < RXBuffLen-1)
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendACK();
|
||||
}
|
||||
// Otherwise when a data byte (the only data byte) is received, return NACK
|
||||
else
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendNACK();
|
||||
}
|
||||
break;
|
||||
|
||||
case TWI_MR_DATA_NACK: // Data byte has been received, NACK has been transmitted. End of transmission.
|
||||
|
||||
/// -- HANDLE DATA BYTE --- ///
|
||||
TWIReceiveBuffer[RXBuffIndex++] = TWDR;
|
||||
// This transmission is complete however do not release bus yet
|
||||
if (TWIInfo.repStart)
|
||||
{
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStart();
|
||||
}
|
||||
// All transmissions are complete, exit
|
||||
else
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStop();
|
||||
}
|
||||
break;
|
||||
|
||||
// ----\/ ---- MT and MR common ----\/ ---- //
|
||||
|
||||
case TWI_MR_SLAR_NACK: // SLA+R transmitted, NACK received
|
||||
case TWI_MT_SLAW_NACK: // SLA+W transmitted, NACK received
|
||||
case TWI_MT_DATA_NACK: // Data byte has been transmitted, NACK received
|
||||
case TWI_LOST_ARBIT: // Arbitration has been lost
|
||||
// Return error and send stop and set mode to ready
|
||||
if (TWIInfo.repStart)
|
||||
{
|
||||
TWIInfo.errorCode = TWI_STATUS;
|
||||
TWISendStart();
|
||||
}
|
||||
// All transmissions are complete, exit
|
||||
else
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = TWI_STATUS;
|
||||
TWISendStop();
|
||||
}
|
||||
break;
|
||||
case TWI_REP_START_SENT: // Repeated start has been transmitted
|
||||
// Set the mode but DO NOT clear TWINT as the next data is not yet ready
|
||||
TWIInfo.mode = RepeatedStartSent;
|
||||
break;
|
||||
|
||||
// ----\/ ---- SLAVE RECEIVER ----\/ ---- //
|
||||
|
||||
// TODO IMPLEMENT SLAVE RECEIVER FUNCTIONALITY
|
||||
|
||||
// ----\/ ---- SLAVE TRANSMITTER ----\/ ---- //
|
||||
|
||||
// TODO IMPLEMENT SLAVE TRANSMITTER FUNCTIONALITY
|
||||
|
||||
// ----\/ ---- MISCELLANEOUS STATES ----\/ ---- //
|
||||
case TWI_NO_RELEVANT_INFO: // It is not really possible to get into this ISR on this condition
|
||||
// Rather, it is there to be manually set between operations
|
||||
break;
|
||||
case TWI_ILLEGAL_START_STOP: // Illegal START/STOP, abort and return error
|
||||
TWIInfo.errorCode = TWI_ILLEGAL_START_STOP;
|
||||
TWIInfo.mode = Ready;
|
||||
TWISendStop();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
82
drivers/avr/TWIlib.h
Normal file
82
drivers/avr/TWIlib.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* TWIlib.h
|
||||
*
|
||||
* Created: 6/01/2014 10:38:42 PM
|
||||
* Author: Chris Herring
|
||||
* http://www.chrisherring.net/all/tutorial-interrupt-driven-twi-interface-for-avr-part1/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TWILIB_H_
|
||||
#define TWILIB_H_
|
||||
// TWI bit rate (was 100000)
|
||||
#define TWI_FREQ 400000
|
||||
// Get TWI status
|
||||
#define TWI_STATUS (TWSR & 0xF8)
|
||||
// Transmit buffer length
|
||||
#define TXMAXBUFLEN 20
|
||||
// Receive buffer length
|
||||
#define RXMAXBUFLEN 20
|
||||
// Global transmit buffer
|
||||
uint8_t TWITransmitBuffer[TXMAXBUFLEN];
|
||||
// Global receive buffer
|
||||
volatile uint8_t TWIReceiveBuffer[RXMAXBUFLEN];
|
||||
// Buffer indexes
|
||||
volatile int TXBuffIndex; // Index of the transmit buffer. Is volatile, can change at any time.
|
||||
int RXBuffIndex; // Current index in the receive buffer
|
||||
// Buffer lengths
|
||||
int TXBuffLen; // The total length of the transmit buffer
|
||||
int RXBuffLen; // The total number of bytes to read (should be less than RXMAXBUFFLEN)
|
||||
|
||||
typedef enum {
|
||||
Ready,
|
||||
Initializing,
|
||||
RepeatedStartSent,
|
||||
MasterTransmitter,
|
||||
MasterReceiver,
|
||||
SlaceTransmitter,
|
||||
SlaveReciever
|
||||
} TWIMode;
|
||||
|
||||
typedef struct TWIInfoStruct{
|
||||
TWIMode mode;
|
||||
uint8_t errorCode;
|
||||
uint8_t repStart;
|
||||
}TWIInfoStruct;
|
||||
TWIInfoStruct TWIInfo;
|
||||
|
||||
|
||||
// TWI Status Codes
|
||||
#define TWI_START_SENT 0x08 // Start sent
|
||||
#define TWI_REP_START_SENT 0x10 // Repeated Start sent
|
||||
// Master Transmitter Mode
|
||||
#define TWI_MT_SLAW_ACK 0x18 // SLA+W sent and ACK received
|
||||
#define TWI_MT_SLAW_NACK 0x20 // SLA+W sent and NACK received
|
||||
#define TWI_MT_DATA_ACK 0x28 // DATA sent and ACK received
|
||||
#define TWI_MT_DATA_NACK 0x30 // DATA sent and NACK received
|
||||
// Master Receiver Mode
|
||||
#define TWI_MR_SLAR_ACK 0x40 // SLA+R sent, ACK received
|
||||
#define TWI_MR_SLAR_NACK 0x48 // SLA+R sent, NACK received
|
||||
#define TWI_MR_DATA_ACK 0x50 // Data received, ACK returned
|
||||
#define TWI_MR_DATA_NACK 0x58 // Data received, NACK returned
|
||||
|
||||
// Miscellaneous States
|
||||
#define TWI_LOST_ARBIT 0x38 // Arbitration has been lost
|
||||
#define TWI_NO_RELEVANT_INFO 0xF8 // No relevant information available
|
||||
#define TWI_ILLEGAL_START_STOP 0x00 // Illegal START or STOP condition has been detected
|
||||
#define TWI_SUCCESS 0xFF // Successful transfer, this state is impossible from TWSR as bit2 is 0 and read only
|
||||
|
||||
|
||||
#define TWISendStart() (TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)) // Send the START signal, enable interrupts and TWI, clear TWINT flag to resume transfer.
|
||||
#define TWISendStop() (TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)) // Send the STOP signal, enable interrupts and TWI, clear TWINT flag.
|
||||
#define TWISendTransmit() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)) // Used to resume a transfer, clear TWINT and ensure that TWI and interrupts are enabled.
|
||||
#define TWISendACK() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA)) // FOR MR mode. Resume a transfer, ensure that TWI and interrupts are enabled and respond with an ACK if the device is addressed as a slave or after it receives a byte.
|
||||
#define TWISendNACK() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)) // FOR MR mode. Resume a transfer, ensure that TWI and interrupts are enabled but DO NOT respond with an ACK if the device is addressed as a slave or after it receives a byte.
|
||||
|
||||
// Function declarations
|
||||
uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart);
|
||||
void TWIInit(void);
|
||||
uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart);
|
||||
uint8_t isTWIReady(void);
|
||||
|
||||
#endif // TWICOMMS_H_
|
258
drivers/avr/is31fl3731.c
Normal file
258
drivers/avr/is31fl3731.c
Normal file
@ -0,0 +1,258 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "is31fl3731.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <string.h>
|
||||
#include "TWIlib.h"
|
||||
#include "progmem.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:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define ISSI_ADDR_DEFAULT 0x74
|
||||
|
||||
#define ISSI_REG_CONFIG 0x00
|
||||
#define ISSI_REG_CONFIG_PICTUREMODE 0x00
|
||||
#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
|
||||
#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
|
||||
|
||||
#define ISSI_CONF_PICTUREMODE 0x00
|
||||
#define ISSI_CONF_AUTOFRAMEMODE 0x04
|
||||
#define ISSI_CONF_AUDIOMODE 0x08
|
||||
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
#define ISSI_REG_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
#define ISSI_COMMANDREGISTER 0xFD
|
||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[TXMAXBUFLEN];
|
||||
|
||||
// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
|
||||
// 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 IS31FL3731_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][144];
|
||||
bool g_pwm_buffer_update_required = false;
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
|
||||
bool g_led_control_registers_update_required = false;
|
||||
|
||||
// This is the bit pattern in the LED control registers
|
||||
// (for matrix A, add one to register for matrix B)
|
||||
//
|
||||
// reg - b7 b6 b5 b4 b3 b2 b1 b0
|
||||
// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
|
||||
// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
|
||||
// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
|
||||
// 0x06 - - , - , - , - , - ,B02,B01,B00
|
||||
// 0x08 - - , - , - , - , - , - , - , -
|
||||
// 0x0A - B17,B16,B15, - , - , - , - , -
|
||||
// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
|
||||
// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
|
||||
// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
|
||||
|
||||
|
||||
void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
|
||||
{
|
||||
g_twi_transfer_buffer[0] = (addr << 1) | 0x00;
|
||||
g_twi_transfer_buffer[1] = reg;
|
||||
g_twi_transfer_buffer[2] = data;
|
||||
|
||||
// Set the error code to have no relevant information
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
// Continuously attempt to transmit data until a successful transmission occurs
|
||||
//while ( TWIInfo.errorCode != 0xFF )
|
||||
//{
|
||||
TWITransmitData( g_twi_transfer_buffer, 3, 0 );
|
||||
//}
|
||||
}
|
||||
|
||||
void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
|
||||
{
|
||||
// assumes bank is already selected
|
||||
|
||||
// transmit PWM registers in 9 transfers of 16 bytes
|
||||
// g_twi_transfer_buffer[] is 20 bytes
|
||||
|
||||
// set the I2C address
|
||||
g_twi_transfer_buffer[0] = (addr << 1) | 0x00;
|
||||
|
||||
// iterate over the pwm_buffer contents at 16 byte intervals
|
||||
for ( int i = 0; i < 144; i += 16 )
|
||||
{
|
||||
// set the first register, e.g. 0x24, 0x34, 0x44, etc.
|
||||
g_twi_transfer_buffer[1] = 0x24 + i;
|
||||
// copy the data from i to i+15
|
||||
// device will auto-increment register for data after the first byte
|
||||
// thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
|
||||
for ( int j = 0; j < 16; j++ )
|
||||
{
|
||||
g_twi_transfer_buffer[2 + j] = pwm_buffer[i + j];
|
||||
}
|
||||
|
||||
// Set the error code to have no relevant information
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
// Continuously attempt to transmit data until a successful transmission occurs
|
||||
while ( TWIInfo.errorCode != 0xFF )
|
||||
{
|
||||
TWITransmitData( g_twi_transfer_buffer, 16 + 2, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_init( uint8_t addr )
|
||||
{
|
||||
// In order to avoid the LEDs being driven with garbage data
|
||||
// in the LED driver's PWM registers, first enable software shutdown,
|
||||
// then set up the mode and other settings, clear the PWM registers,
|
||||
// then disable software shutdown.
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// enable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
_delay_ms( 10 );
|
||||
|
||||
// picture mode
|
||||
IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
|
||||
// display frame 0
|
||||
IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
|
||||
// audio sync off
|
||||
IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
|
||||
|
||||
// select bank 0
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
// turn off all LEDs in the LED control register
|
||||
for ( int i = 0x00; i <= 0x11; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// turn off all LEDs in the blink control register (not really needed)
|
||||
for ( int i = 0x12; i <= 0x23; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// set PWM on all LEDs to 0
|
||||
for ( int i = 0x24; i <= 0xB3; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// disable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
|
||||
|
||||
// select bank 0 and leave it selected.
|
||||
// most usage after initialization is just writing PWM buffers in bank 0
|
||||
// as there's not much point in double-buffering
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
}
|
||||
|
||||
void IS31FL3731_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];
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.r - 0x24] = red;
|
||||
g_pwm_buffer[led.driver][led.g - 0x24] = green;
|
||||
g_pwm_buffer[led.driver][led.b - 0x24] = blue;
|
||||
g_pwm_buffer_update_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
IS31FL3731_set_color( i, red, green, blue );
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_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 - 0x24) / 8;
|
||||
uint8_t control_register_g = (led.g - 0x24) / 8;
|
||||
uint8_t control_register_b = (led.b - 0x24) / 8;
|
||||
uint8_t bit_r = (led.r - 0x24) % 8;
|
||||
uint8_t bit_g = (led.g - 0x24) % 8;
|
||||
uint8_t bit_b = (led.b - 0x24) % 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 IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_pwm_buffer_update_required )
|
||||
{
|
||||
IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
|
||||
IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
|
||||
}
|
||||
g_pwm_buffer_update_required = false;
|
||||
}
|
||||
|
||||
void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_led_control_registers_update_required )
|
||||
{
|
||||
for ( int i=0; i<18; i++ )
|
||||
{
|
||||
IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
|
||||
IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
214
drivers/avr/is31fl3731.h
Normal file
214
drivers/avr/is31fl3731.h
Normal file
@ -0,0 +1,214 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef IS31FL3731_DRIVER_H
|
||||
#define IS31FL3731_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 IS31FL3731_init( uint8_t addr );
|
||||
void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data );
|
||||
void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
|
||||
|
||||
void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
|
||||
void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
|
||||
|
||||
void IS31FL3731_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 IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
|
||||
void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
|
||||
|
||||
#define C1_1 0x24
|
||||
#define C1_2 0x25
|
||||
#define C1_3 0x26
|
||||
#define C1_4 0x27
|
||||
#define C1_5 0x28
|
||||
#define C1_6 0x29
|
||||
#define C1_7 0x2A
|
||||
#define C1_8 0x2B
|
||||
|
||||
#define C1_9 0x2C
|
||||
#define C1_10 0x2D
|
||||
#define C1_11 0x2E
|
||||
#define C1_12 0x2F
|
||||
#define C1_13 0x30
|
||||
#define C1_14 0x31
|
||||
#define C1_15 0x32
|
||||
#define C1_16 0x33
|
||||
|
||||
#define C2_1 0x34
|
||||
#define C2_2 0x35
|
||||
#define C2_3 0x36
|
||||
#define C2_4 0x37
|
||||
#define C2_5 0x38
|
||||
#define C2_6 0x39
|
||||
#define C2_7 0x3A
|
||||
#define C2_8 0x3B
|
||||
|
||||
#define C2_9 0x3C
|
||||
#define C2_10 0x3D
|
||||
#define C2_11 0x3E
|
||||
#define C2_12 0x3F
|
||||
#define C2_13 0x40
|
||||
#define C2_14 0x41
|
||||
#define C2_15 0x42
|
||||
#define C2_16 0x43
|
||||
|
||||
#define C3_1 0x44
|
||||
#define C3_2 0x45
|
||||
#define C3_3 0x46
|
||||
#define C3_4 0x47
|
||||
#define C3_5 0x48
|
||||
#define C3_6 0x49
|
||||
#define C3_7 0x4A
|
||||
#define C3_8 0x4B
|
||||
|
||||
#define C3_9 0x4C
|
||||
#define C3_10 0x4D
|
||||
#define C3_11 0x4E
|
||||
#define C3_12 0x4F
|
||||
#define C3_13 0x50
|
||||
#define C3_14 0x51
|
||||
#define C3_15 0x52
|
||||
#define C3_16 0x53
|
||||
|
||||
#define C4_1 0x54
|
||||
#define C4_2 0x55
|
||||
#define C4_3 0x56
|
||||
#define C4_4 0x57
|
||||
#define C4_5 0x58
|
||||
#define C4_6 0x59
|
||||
#define C4_7 0x5A
|
||||
#define C4_8 0x5B
|
||||
|
||||
#define C4_9 0x5C
|
||||
#define C4_10 0x5D
|
||||
#define C4_11 0x5E
|
||||
#define C4_12 0x5F
|
||||
#define C4_13 0x60
|
||||
#define C4_14 0x61
|
||||
#define C4_15 0x62
|
||||
#define C4_16 0x63
|
||||
|
||||
#define C5_1 0x64
|
||||
#define C5_2 0x65
|
||||
#define C5_3 0x66
|
||||
#define C5_4 0x67
|
||||
#define C5_5 0x68
|
||||
#define C5_6 0x69
|
||||
#define C5_7 0x6A
|
||||
#define C5_8 0x6B
|
||||
|
||||
#define C5_9 0x6C
|
||||
#define C5_10 0x6D
|
||||
#define C5_11 0x6E
|
||||
#define C5_12 0x6F
|
||||
#define C5_13 0x70
|
||||
#define C5_14 0x71
|
||||
#define C5_15 0x72
|
||||
#define C5_16 0x73
|
||||
|
||||
#define C6_1 0x74
|
||||
#define C6_2 0x75
|
||||
#define C6_3 0x76
|
||||
#define C6_4 0x77
|
||||
#define C6_5 0x78
|
||||
#define C6_6 0x79
|
||||
#define C6_7 0x7A
|
||||
#define C6_8 0x7B
|
||||
|
||||
#define C6_9 0x7C
|
||||
#define C6_10 0x7D
|
||||
#define C6_11 0x7E
|
||||
#define C6_12 0x7F
|
||||
#define C6_13 0x80
|
||||
#define C6_14 0x81
|
||||
#define C6_15 0x82
|
||||
#define C6_16 0x83
|
||||
|
||||
#define C7_1 0x84
|
||||
#define C7_2 0x85
|
||||
#define C7_3 0x86
|
||||
#define C7_4 0x87
|
||||
#define C7_5 0x88
|
||||
#define C7_6 0x89
|
||||
#define C7_7 0x8A
|
||||
#define C7_8 0x8B
|
||||
|
||||
#define C7_9 0x8C
|
||||
#define C7_10 0x8D
|
||||
#define C7_11 0x8E
|
||||
#define C7_12 0x8F
|
||||
#define C7_13 0x90
|
||||
#define C7_14 0x91
|
||||
#define C7_15 0x92
|
||||
#define C7_16 0x93
|
||||
|
||||
#define C8_1 0x94
|
||||
#define C8_2 0x95
|
||||
#define C8_3 0x96
|
||||
#define C8_4 0x97
|
||||
#define C8_5 0x98
|
||||
#define C8_6 0x99
|
||||
#define C8_7 0x9A
|
||||
#define C8_8 0x9B
|
||||
|
||||
#define C8_9 0x9C
|
||||
#define C8_10 0x9D
|
||||
#define C8_11 0x9E
|
||||
#define C8_12 0x9F
|
||||
#define C8_13 0xA0
|
||||
#define C8_14 0xA1
|
||||
#define C8_15 0xA2
|
||||
#define C8_16 0xA3
|
||||
|
||||
#define C9_1 0xA4
|
||||
#define C9_2 0xA5
|
||||
#define C9_3 0xA6
|
||||
#define C9_4 0xA7
|
||||
#define C9_5 0xA8
|
||||
#define C9_6 0xA9
|
||||
#define C9_7 0xAA
|
||||
#define C9_8 0xAB
|
||||
|
||||
#define C9_9 0xAC
|
||||
#define C9_10 0xAD
|
||||
#define C9_11 0xAE
|
||||
#define C9_12 0xAF
|
||||
#define C9_13 0xB0
|
||||
#define C9_14 0xB1
|
||||
#define C9_15 0xB2
|
||||
#define C9_16 0xB3
|
||||
|
||||
|
||||
|
||||
#endif // IS31FL3731_DRIVER_H
|
@ -65,20 +65,37 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define LED_BRIGHTNESS_HI 255
|
||||
|
||||
/* ws2812 RGB LED */
|
||||
#define RGB_DI_PIN D7
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#define RGBLED_NUM 15 // Number of LEDs
|
||||
#define RGBLIGHT_HUE_STEP 12
|
||||
#define RGBLIGHT_SAT_STEP 255
|
||||
#define RGBLIGHT_VAL_STEP 12
|
||||
// #define RGB_DI_PIN D7
|
||||
// #define RGBLIGHT_ANIMATIONS
|
||||
// #define RGBLED_NUM 15 // Number of LEDs
|
||||
// #define RGBLIGHT_HUE_STEP 12
|
||||
// #define RGBLIGHT_SAT_STEP 255
|
||||
// #define RGBLIGHT_VAL_STEP 12
|
||||
|
||||
/* fix space cadet rollover issue */
|
||||
#define DISABLE_SPACE_CADET_ROLLOVER
|
||||
// /* fix space cadet rollover issue */
|
||||
// #define DISABLE_SPACE_CADET_ROLLOVER
|
||||
|
||||
// #define RGB_MIDI
|
||||
#define RGBW_BB_TWI
|
||||
// // #define RGB_MIDI
|
||||
// #define RGBW_BB_TWI
|
||||
|
||||
#define RGBW 1
|
||||
// #define RGBW 1
|
||||
|
||||
// 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:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define DRIVER_ADDR_1 0b1110100
|
||||
#define DRIVER_ADDR_2 0b1110111
|
||||
|
||||
#define DRIVER_COUNT 2
|
||||
#define DRIVER_1_LED_TOTAL 24
|
||||
#define DRIVER_2_LED_TOTAL 24
|
||||
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
|
||||
|
||||
//#define RGB_MATRIX_ANIMATIONS
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCE 15
|
||||
|
@ -134,3 +134,129 @@ const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||
/* driver
|
||||
* | R location
|
||||
* | | G location
|
||||
* | | | B location
|
||||
* | | | | */
|
||||
{0, C3_1, C2_1, C4_1}, // LED1 on right
|
||||
{0, C6_1, C5_1, C7_1}, // LED2
|
||||
{0, C4_2, C3_2, C5_2}, // LED3
|
||||
{0, C7_2, C6_2, C8_2}, // LED4
|
||||
{0, C2_3, C1_3, C3_3}, // LED5
|
||||
{0, C5_3, C4_3, C6_3}, // LED6
|
||||
{0, C8_3, C7_3, C9_3}, // LED7
|
||||
{0, C2_4, C1_4, C3_4}, // LED8
|
||||
{0, C6_4, C5_4, C7_4}, // LED9
|
||||
{0, C2_5, C1_5, C3_5}, // LED10
|
||||
{0, C7_5, C6_5, C8_5}, // LED11
|
||||
{0, C2_6, C1_6, C3_6}, // LED12
|
||||
{0, C5_6, C4_6, C6_6}, // LED13
|
||||
{0, C8_6, C7_6, C9_6}, // LED14
|
||||
{0, C2_7, C1_7, C3_7}, // LED15
|
||||
{0, C5_7, C4_7, C6_7}, // LED16
|
||||
{0, C2_8, C1_8, C3_8}, // LED17
|
||||
{0, C5_8, C4_8, C6_8}, // LED18
|
||||
|
||||
{0, C3_9, C2_9, C4_9}, // LED19
|
||||
{0, C6_9, C5_9, C7_9}, // LED20
|
||||
{0, C4_10, C3_10, C5_10}, // LED21
|
||||
{0, C7_10, C6_10, C8_10}, // LED22
|
||||
{0, C2_11, C1_11, C3_11}, // LED23
|
||||
{0, C5_11, C4_11, C6_11}, // LED24
|
||||
|
||||
{1, C3_1, C2_1, C4_1}, // LED1 on left
|
||||
{1, C6_1, C5_1, C7_1}, // LED2
|
||||
{1, C4_2, C3_2, C5_2}, // LED3
|
||||
{1, C7_2, C6_2, C8_2}, // LED4
|
||||
{1, C2_3, C1_3, C3_3}, // LED5
|
||||
{1, C5_3, C4_3, C6_3}, // LED6
|
||||
{1, C8_3, C7_3, C9_3}, // LED7
|
||||
{1, C2_4, C1_4, C3_4}, // LED8
|
||||
{1, C6_4, C5_4, C7_4}, // LED9
|
||||
{1, C2_5, C1_5, C3_5}, // LED10
|
||||
{1, C7_5, C6_5, C8_5}, // LED11
|
||||
{1, C2_6, C1_6, C3_6}, // LED12
|
||||
{1, C5_6, C4_6, C6_6}, // LED13
|
||||
{1, C8_6, C7_6, C9_6}, // LED14
|
||||
{1, C2_7, C1_7, C3_7}, // LED15
|
||||
{1, C5_7, C4_7, C6_7}, // LED16
|
||||
{1, C2_8, C1_8, C3_8}, // LED17
|
||||
{1, C5_8, C4_8, C6_8}, // LED18
|
||||
|
||||
{1, C3_9, C2_9, C4_9}, // LED19
|
||||
{1, C6_9, C5_9, C7_9}, // LED20
|
||||
{1, C4_10, C3_10, C5_10}, // LED21
|
||||
{1, C7_10, C6_10, C8_10}, // LED22
|
||||
{1, C2_11, C1_11, C3_11}, // LED23
|
||||
{1, C5_11, C4_11, C6_11} // LED24
|
||||
};
|
||||
|
||||
|
||||
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
|
||||
|
||||
/*{row | col << 4}
|
||||
| {x=0..224, y=0..64}
|
||||
| | modifier
|
||||
| | | */
|
||||
{{0|(0<<4)}, {24.9*5, 16*0}, 0}, // LED 1 on right
|
||||
{{0|(1<<4)}, {24.9*6, 16*0}, 0}, // LED 2
|
||||
{{0|(2<<4)}, {24.9*7, 16*0}, 0}, // LED 3
|
||||
{{0|(3<<4)}, {24.9*8, 16*0}, 0}, // LED 4
|
||||
{{0|(4<<4)}, {24.9*9, 16*0}, 0}, // LED 5
|
||||
|
||||
{{1|(5<<4)}, {24.9*5, 16*1}, 0}, // LED 6
|
||||
{{1|(6<<4)}, {24.9*6, 16*1}, 0}, // LED 7
|
||||
{{1|(7<<4)}, {24.9*7, 16*1}, 0}, // LED 8
|
||||
{{1|(8<<4)}, {24.9*8, 16*1}, 0}, // LED 9
|
||||
{{1|(9<<4)}, {24.9*9, 16*1}, 0}, // LED 10
|
||||
|
||||
{{2|(5<<4)}, {24.9*5, 16*2}, 0}, // LED 11
|
||||
{{2|(6<<4)}, {24.9*6, 16*2}, 0}, // LED 12
|
||||
{{2|(7<<4)}, {24.9*7, 16*2}, 0}, // LED 13
|
||||
{{2|(8<<4)}, {24.9*8, 16*2}, 0}, // LED 14
|
||||
{{2|(9<<4)}, {24.9*9, 16*2}, 0}, // LED 15
|
||||
|
||||
{{3|(5<<4)}, {24.9*5, 16*2}, 0}, // LED 16
|
||||
{{3|(6<<4)}, {24.9*6, 16*2}, 0}, // LED 17
|
||||
{{3|(7<<4)}, {24.9*7, 16*2}, 0}, // LED 18
|
||||
{{3|(8<<4)}, {24.9*8, 16*2}, 0}, // LED 19
|
||||
{{3|(9<<4)}, {24.9*9, 16*2}, 0}, // LED 20
|
||||
|
||||
{{4|(6<<4)}, {24.9*6, 16*2}, 0}, // LED 21
|
||||
{{4|(7<<4)}, {24.9*7, 16*2}, 0}, // LED 22
|
||||
{{4|(8<<4)}, {24.9*8, 16*2}, 0}, // LED 23
|
||||
{{4|(9<<4)}, {24.9*9, 16*2}, 0}, // LED 24
|
||||
|
||||
{{0|(0<<4)}, {24.9*4, 16*0}, 0}, // LED 1 on left
|
||||
{{0|(1<<4)}, {24.9*3, 16*0}, 0}, // LED 2
|
||||
{{0|(2<<4)}, {24.9*2, 16*0}, 0}, // LED 3
|
||||
{{0|(3<<4)}, {24.9*1, 16*0}, 0}, // LED 4
|
||||
{{0|(4<<4)}, {24.9*0, 16*0}, 0}, // LED 5
|
||||
|
||||
{{1|(5<<4)}, {24.9*4, 16*1}, 0}, // LED 6
|
||||
{{1|(6<<4)}, {24.9*3, 16*1}, 0}, // LED 7
|
||||
{{1|(7<<4)}, {24.9*2, 16*1}, 0}, // LED 8
|
||||
{{1|(8<<4)}, {24.9*1, 16*1}, 0}, // LED 9
|
||||
{{1|(9<<4)}, {24.9*0, 16*1}, 0}, // LED 10
|
||||
|
||||
{{2|(5<<4)}, {24.9*4, 16*2}, 0}, // LED 11
|
||||
{{2|(6<<4)}, {24.9*3, 16*2}, 0}, // LED 12
|
||||
{{2|(7<<4)}, {24.9*2, 16*2}, 0}, // LED 13
|
||||
{{2|(8<<4)}, {24.9*1, 16*2}, 0}, // LED 14
|
||||
{{2|(9<<4)}, {24.9*0, 16*2}, 0}, // LED 15
|
||||
|
||||
{{3|(5<<4)}, {24.9*4, 16*2}, 0}, // LED 16
|
||||
{{3|(6<<4)}, {24.9*3, 16*2}, 0}, // LED 17
|
||||
{{3|(7<<4)}, {24.9*2, 16*2}, 0}, // LED 18
|
||||
{{3|(8<<4)}, {24.9*1, 16*2}, 0}, // LED 19
|
||||
{{3|(9<<4)}, {24.9*0, 16*2}, 0}, // LED 20
|
||||
|
||||
{{4|(6<<4)}, {24.9*3, 16*2}, 0}, // LED 21
|
||||
{{4|(7<<4)}, {24.9*3, 16*2}, 0}, // LED 22
|
||||
{{4|(8<<4)}, {24.9*1, 16*2}, 0}, // LED 23
|
||||
{{4|(9<<4)}, {24.9*0, 16*2}, 0}, // LED 24
|
||||
};
|
||||
|
@ -81,6 +81,7 @@ UNICODE_ENABLE = yes # Unicode
|
||||
ONEHAND_ENABLE = yes # Allow swapping hands of keyboard
|
||||
SLEEP_LED_ENABLE = no
|
||||
API_SYSEX_ENABLE = no
|
||||
RGBLIGHT_ENABLE = yes
|
||||
RGBLIGHT_ENABLE = no
|
||||
RGB_MATRIX_ENABLE = yes
|
||||
|
||||
LAYOUTS = ergodox
|
@ -1,64 +0,0 @@
|
||||
mechmini
|
||||
========
|
||||
|
||||
A compact ortholinear/staggered keyboard.
|
||||
|
||||
Keyboard Maintainer: QMK Community
|
||||
Hardware Supported: mechmini PCB
|
||||
Hardware Availability: https://mechkeys.ca/collections/keyboards/products/mechmini-2-0-pcb
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make mechmini:default
|
||||
|
||||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
|
||||
|
||||
## Mechmini Notes
|
||||
|
||||
Note that this is a complete replacement for the firmware, so you won't be
|
||||
using Bootmapper Client to change any keyboard settings, since not all the
|
||||
USB report options are supported.
|
||||
|
||||
## Installing
|
||||
|
||||
First, install the requirements. These commands are for OSX, but all you
|
||||
need is the AVR toolchain and `bootloadHID` for flashing:
|
||||
|
||||
```
|
||||
$ brew cask install crosspack-avr
|
||||
$ brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb
|
||||
```
|
||||
|
||||
In order to use the `./program` script, which can reboot the board into
|
||||
the bootloader, you'll need Python 2 with PyUSB installed:
|
||||
|
||||
```
|
||||
$ pip install pyusb
|
||||
```
|
||||
|
||||
Then, with the keyboard plugged in, simply run this command from the
|
||||
`qmk_firmware` directory:
|
||||
|
||||
```
|
||||
$ make mechmini:program
|
||||
```
|
||||
|
||||
If you prefer, you can just build it and flash the firmware directly with
|
||||
`bootloadHID` if you boot the board while holding down `L_Ctrl` to keep it
|
||||
in the bootloader:
|
||||
|
||||
```
|
||||
$ make mechmini
|
||||
$ bootloadHID -r mechmini_default.hex
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
From my experience, it's really hard to brick these boards. But these
|
||||
tricks have been useful when it got stuck in a weird scenario.
|
||||
|
||||
1. Try plugging the board in while pressing `L_Ctrl`. This will force it
|
||||
to boot only the bootloader without loading the firmware. Once this is
|
||||
done, just reflash the board with the original firmware.
|
||||
2. Sometimes USB hubs can act weird, so try connecting the board directly
|
||||
to your computer or plugging/unplugging the USB hub.
|
@ -1,68 +1,30 @@
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "../../config.h"
|
||||
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@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/>.
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
#define TAPPING_TERM 200
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
#define MIDI_BASIC
|
||||
|
||||
#include "config_common.h"
|
||||
/* 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
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6060
|
||||
#define MANUFACTURER Ortholinear Keyboards
|
||||
#define PRODUCT The Planck Keyboard
|
||||
#define DESCRIPTION A compact ortholinear keyboard
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 4
|
||||
#define MATRIX_COLS 12
|
||||
|
||||
/* Planck PCB default pin-out */
|
||||
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
|
||||
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
#define AUDIO_VOICES
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* 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
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 2
|
||||
|
||||
#define MOUSEKEY_INTERVAL 20
|
||||
#define MOUSEKEY_DELAY 0
|
||||
@ -70,29 +32,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MOUSEKEY_MAX_SPEED 7
|
||||
#define MOUSEKEY_WHEEL_DELAY 0
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
#ifdef SUBPROJECT_rev3
|
||||
#include "rev3/config.h"
|
||||
#endif
|
||||
#ifdef SUBPROJECT_rev4
|
||||
#include "rev4/config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,91 +1,29 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
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 CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* Tap-dance interval definition */
|
||||
#define TAPPING_TERM 200
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6060
|
||||
#define MANUFACTURER Ortholinear Keyboards
|
||||
#define PRODUCT The Planck Keyboard
|
||||
#define DESCRIPTION A compact ortholinear keyboard
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 4
|
||||
#define MATRIX_COLS 12
|
||||
|
||||
/* Planck PCB default pin-out */
|
||||
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
|
||||
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* 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
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
#include "../../config.h"
|
||||
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* disable debug print */
|
||||
//#define NO_DEBUG
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* disable print */
|
||||
//#define NO_PRINT
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
#define MIDI_BASIC
|
||||
|
||||
/* disable action features */
|
||||
//#define NO_ACTION_LAYER
|
||||
//#define NO_ACTION_TAPPING
|
||||
//#define NO_ACTION_ONESHOT
|
||||
//#define NO_ACTION_MACRO
|
||||
//#define NO_ACTION_FUNCTION
|
||||
/* 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
|
||||
|
||||
#ifdef SUBPROJECT_rev3
|
||||
#include "rev3/config.h"
|
||||
#endif
|
||||
#ifdef SUBPROJECT_rev4
|
||||
#include "rev4/config.h"
|
||||
#endif
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 2
|
||||
|
||||
#endif
|
@ -163,9 +163,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* `-----------------------------------------------------------------------------------'
|
||||
*/
|
||||
[_ADJUST] = {
|
||||
{_______, RESET, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,_______, _______, KC_DEL },
|
||||
{_______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL },
|
||||
{_______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______},
|
||||
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
|
||||
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______},
|
||||
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "../../config.h"
|
||||
#include "config_common.h"
|
||||
|
||||
#ifdef AUDIO_ENABLE
|
||||
#define STARTUP_SONG SONG(SONIC_RING)
|
||||
|
@ -29,31 +29,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
/*
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* number of backlight levels */
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
#define MIDI_BASIC
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* 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
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
#define BACKLIGHT_BREATHING
|
||||
/* 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 2
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
@ -72,6 +69,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* Only print user print statements */
|
||||
#define USER_PRINT
|
||||
|
||||
#define BACKLIGHT_BREATHING
|
||||
|
||||
/* disable action features */
|
||||
//#define NO_ACTION_LAYER
|
||||
@ -79,5 +77,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//#define NO_ACTION_ONESHOT
|
||||
//#define NO_ACTION_MACRO
|
||||
//#define NO_ACTION_FUNCTION
|
||||
|
||||
#endif
|
||||
|
@ -1,82 +1,30 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
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 CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6060
|
||||
#define MANUFACTURER Ortholinear Keyboards
|
||||
#define PRODUCT The Planck Keyboard
|
||||
#define DESCRIPTION A compact ortholinear keyboard
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 4
|
||||
#define MATRIX_COLS 12
|
||||
|
||||
/* Planck PCB default pin-out */
|
||||
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
|
||||
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* 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
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
#include "../../config.h"
|
||||
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* disable debug print */
|
||||
//#define NO_DEBUG
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* disable print */
|
||||
//#define NO_PRINT
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
#define MIDI_BASIC
|
||||
|
||||
/* disable action features */
|
||||
//#define NO_ACTION_LAYER
|
||||
//#define NO_ACTION_TAPPING
|
||||
//#define NO_ACTION_ONESHOT
|
||||
//#define NO_ACTION_MACRO
|
||||
//#define NO_ACTION_FUNCTION
|
||||
/* 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 2
|
||||
|
||||
/* prevent the modifiers from being stuck, sacrificing some memory */
|
||||
#define PREVENT_STUCK_MODIFIERS
|
||||
@ -86,11 +34,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define DYNAMIC_MACRO_SIZE 256
|
||||
|
||||
#ifdef SUBPROJECT_rev3
|
||||
#include "rev3/config.h"
|
||||
#endif
|
||||
#ifdef SUBPROJECT_rev4
|
||||
#include "rev4/config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,55 +1,30 @@
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "../../config.h"
|
||||
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@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/>.
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
#include "config_common.h"
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
#define MIDI_BASIC
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6060
|
||||
#define MANUFACTURER Ortholinear Keyboards
|
||||
#define PRODUCT The Planck Keyboard
|
||||
#define DESCRIPTION A compact ortholinear keyboard
|
||||
/* 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
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 4
|
||||
#define MATRIX_COLS 12
|
||||
|
||||
/* Planck PCB default pin-out */
|
||||
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
|
||||
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
//#define BACKLIGHT_BREATHING // LED breathing
|
||||
/* number of backlight levels */
|
||||
#define BACKLIGHT_LEVELS 5
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 2
|
||||
|
||||
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||
//#define LOCKING_SUPPORT_ENABLE
|
||||
@ -84,11 +59,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//#define DYNAMIC_MACRO_ENABLE // Enable if you need to use the macro functionality
|
||||
//#define SPACE_CADET // Parenthesis on L/R shift
|
||||
|
||||
#ifdef SUBPROJECT_rev3
|
||||
#include "rev3/config.h"
|
||||
#endif
|
||||
#ifdef SUBPROJECT_rev4
|
||||
#include "rev4/config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
56
keyboards/planck/light/config.h
Normal file
56
keyboards/planck/light/config.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef LIGHT_CONFIG_H
|
||||
#define LIGHT_CONFIG_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
#undef PRODUCT
|
||||
#define PRODUCT Planck Light
|
||||
#undef PRODUCT_ID
|
||||
#define PRODUCT_ID 0x6065
|
||||
#define DEVICE_VER 0x0001
|
||||
|
||||
#undef MATRIX_ROW_PINS
|
||||
#undef MATRIX_COL_PINS
|
||||
|
||||
#define MATRIX_ROW_PINS { B0, E7, F0, F1 }
|
||||
#define MATRIX_COL_PINS { E6, E3, E4, D3, D4, D5, C0, A7, A6, E1, E0, D7 }
|
||||
|
||||
#define C6_AUDIO
|
||||
#define B5_AUDIO
|
||||
|
||||
#undef BACKLIGHT_PIN
|
||||
|
||||
#define BACKLIGHT_PIN A5
|
||||
|
||||
/* Size of Bootloaders in bytes:
|
||||
* Atmel DFU loader(ATmega32U4) 4096
|
||||
* Atmel DFU loader(AT90USB128) 8192
|
||||
* LUFA bootloader(ATmega32U4) 4096
|
||||
* Arduino Caterina(ATmega32U4) 4096
|
||||
* USBaspLoader(ATmega***) 2048
|
||||
* Teensy halfKay(ATmega32U4) 512
|
||||
* Teensy++ halfKay(AT90USB128) 1024
|
||||
*/
|
||||
#define BOOTLOADER_SIZE 8192
|
||||
|
||||
#define NO_USB_STARTUP_CHECK
|
||||
|
||||
#define PLANCK_MIT_LAYOUT
|
||||
|
||||
// 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:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define DRIVER_ADDR_1 0b1110100
|
||||
#define DRIVER_ADDR_2 0b1110110
|
||||
|
||||
#define DRIVER_COUNT 2
|
||||
#define DRIVER_1_LED_TOTAL 25
|
||||
#define DRIVER_2_LED_TOTAL 24
|
||||
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
|
||||
|
||||
|
||||
#endif
|
168
keyboards/planck/light/light.c
Normal file
168
keyboards/planck/light/light.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* Copyright 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "light.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, C1_3, C2_3, C3_3},
|
||||
{0, C1_4, C2_4, C3_4},
|
||||
{0, C1_5, C2_5, C3_5},
|
||||
{0, C1_11, C2_11, C3_11},
|
||||
{0, C1_12, C2_12, C3_12},
|
||||
{0, C1_13, C2_13, C3_13},
|
||||
{1, C1_3, C2_3, C3_3},
|
||||
{1, C1_4, C2_4, C3_4},
|
||||
{1, C1_5, C2_5, C3_5},
|
||||
{1, C1_11, C2_11, C3_11},
|
||||
{1, C1_12, C2_12, C3_12},
|
||||
{1, C1_13, C2_13, C3_13},
|
||||
|
||||
{0, C1_6, C2_6, C3_6},
|
||||
{0, C1_7, C2_7, C3_7},
|
||||
{0, C1_8, C2_8, C3_8},
|
||||
{0, C1_14, C2_14, C3_14},
|
||||
{0, C1_15, C2_15, C3_15},
|
||||
{0, C1_16, C2_16, C3_16},
|
||||
{1, C1_6, C2_6, C3_6},
|
||||
{1, C1_7, C2_7, C3_7},
|
||||
{1, C1_8, C2_8, C3_8},
|
||||
{1, C1_14, C2_14, C3_14},
|
||||
{1, C1_15, C2_15, C3_15},
|
||||
{1, C1_16, C2_16, C3_16},
|
||||
|
||||
{0, C9_1, C8_1, C7_1},
|
||||
{0, C9_2, C8_2, C7_2},
|
||||
{0, C9_3, C8_3, C7_3},
|
||||
{0, C9_9, C8_9, C7_9},
|
||||
{0, C9_10, C8_10, C7_10},
|
||||
{0, C9_11, C8_11, C7_11},
|
||||
{1, C9_1, C8_1, C7_1},
|
||||
{1, C9_2, C8_2, C7_2},
|
||||
{1, C9_3, C8_3, C7_3},
|
||||
{1, C9_9, C8_9, C7_9},
|
||||
{1, C9_10, C8_10, C7_10},
|
||||
{1, C9_11, C8_11, C7_11},
|
||||
|
||||
{0, C9_4, C8_4, C7_4},
|
||||
{0, C9_5, C8_5, C7_5},
|
||||
{0, C9_6, C8_6, C7_6},
|
||||
{0, C9_12, C8_12, C7_12},
|
||||
{0, C9_13, C8_13, C7_13},
|
||||
{0, C9_14, C8_14, C7_14},
|
||||
{0, C9_15, C8_15, C6_14}, // middle 2u switch
|
||||
{1, C9_4, C8_4, C7_4},
|
||||
{1, C9_5, C8_5, C7_5},
|
||||
{1, C9_6, C8_6, C7_6},
|
||||
{1, C9_12, C8_12, C7_12},
|
||||
{1, C9_13, C8_13, C7_13},
|
||||
{1, C9_14, C8_14, C7_14}
|
||||
};
|
||||
|
||||
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, 21.33*3}, 0},
|
||||
{{3|(5<<4)}, {20.36*5.5,21.33*3}, 0},
|
||||
{{3|(6<<4)}, {20.36*6, 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) {
|
||||
|
||||
// Turn status LED on
|
||||
DDRD |= (1<<6);
|
||||
PORTD |= (1<<6);
|
||||
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
bool process_record_kb(uint16_t keycode, keyrecord_t *record)
|
||||
{
|
||||
return process_record_user(keycode, record);
|
||||
}
|
||||
|
||||
void matrix_scan_kb(void)
|
||||
{
|
||||
matrix_scan_user();
|
||||
}
|
||||
|
||||
void suspend_power_down_kb(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(true);
|
||||
}
|
||||
|
||||
void suspend_wakeup_init_kb(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(false);
|
||||
}
|
23
keyboards/planck/light/light.h
Normal file
23
keyboards/planck/light/light.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* Copyright 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIGHT_H
|
||||
#define LIGHT_H
|
||||
|
||||
#include "planck.h"
|
||||
#include "rgb_matrix.h"
|
||||
|
||||
#endif
|
5
keyboards/planck/light/rules.mk
Normal file
5
keyboards/planck/light/rules.mk
Normal file
@ -0,0 +1,5 @@
|
||||
MIDI_ENABLE = yes
|
||||
AUDIO_ENABLE = yes # Audio output on port C6
|
||||
RGB_MATRIX_ENABLE = yes
|
||||
|
||||
MCU = at90usb1286
|
@ -10,6 +10,7 @@ const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_kb(void) {
|
||||
// Turn status LED on
|
||||
DDRE |= (1<<6);
|
||||
|
@ -38,5 +38,8 @@
|
||||
#ifdef KEYBOARD_planck_rev4
|
||||
#include "rev4.h"
|
||||
#endif
|
||||
#ifdef KEYBOARD_planck_light
|
||||
#include "light.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1 +1,10 @@
|
||||
|
||||
# Boot Section Size in *bytes*
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
AUDIO_ENABLE = no # Audio output on port C6
|
@ -1 +1,9 @@
|
||||
# Boot Section Size in *bytes*
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
AUDIO_ENABLE = yes # Audio output on port C6
|
@ -37,15 +37,6 @@ F_USB = $(F_CPU)
|
||||
# Interrupt driven control endpoint task(+60)
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
|
||||
# Boot Section Size in *bytes*
|
||||
# Teensy halfKay 512
|
||||
# Teensy++ halfKay 1024
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
# USBaspLoader 2048
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
# Build Options
|
||||
# change to "no" to disable the options, or define them in the Makefile in
|
||||
# the appropriate keymap folder that will get included automatically
|
||||
|
@ -184,6 +184,9 @@ void audio_init()
|
||||
#ifdef B5_AUDIO
|
||||
TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
|
||||
TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
|
||||
|
||||
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
|
||||
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
|
||||
#endif
|
||||
|
||||
audio_initialized = true;
|
||||
|
87
quantum/color.c
Normal file
87
quantum/color.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
*
|
||||
* 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 "color.h"
|
||||
#include "led_tables.h"
|
||||
#include "progmem.h"
|
||||
|
||||
RGB hsv_to_rgb( HSV hsv )
|
||||
{
|
||||
RGB rgb;
|
||||
uint8_t region, p, q, t;
|
||||
uint16_t h, s, v, remainder;
|
||||
|
||||
if ( hsv.s == 0 )
|
||||
{
|
||||
rgb.r = hsv.v;
|
||||
rgb.g = hsv.v;
|
||||
rgb.b = hsv.v;
|
||||
return rgb;
|
||||
}
|
||||
|
||||
h = hsv.h;
|
||||
s = hsv.s;
|
||||
v = hsv.v;
|
||||
|
||||
region = h / 43;
|
||||
remainder = (h - (region * 43)) * 6;
|
||||
|
||||
p = (v * (255 - s)) >> 8;
|
||||
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
|
||||
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
|
||||
|
||||
switch ( region )
|
||||
{
|
||||
case 0:
|
||||
rgb.r = v;
|
||||
rgb.g = t;
|
||||
rgb.b = p;
|
||||
break;
|
||||
case 1:
|
||||
rgb.r = q;
|
||||
rgb.g = v;
|
||||
rgb.b = p;
|
||||
break;
|
||||
case 2:
|
||||
rgb.r = p;
|
||||
rgb.g = v;
|
||||
rgb.b = t;
|
||||
break;
|
||||
case 3:
|
||||
rgb.r = p;
|
||||
rgb.g = q;
|
||||
rgb.b = v;
|
||||
break;
|
||||
case 4:
|
||||
rgb.r = t;
|
||||
rgb.g = p;
|
||||
rgb.b = v;
|
||||
break;
|
||||
default:
|
||||
rgb.r = v;
|
||||
rgb.g = p;
|
||||
rgb.b = q;
|
||||
break;
|
||||
}
|
||||
|
||||
rgb.r = pgm_read_byte( &CIE1931_CURVE[rgb.r] );
|
||||
rgb.g = pgm_read_byte( &CIE1931_CURVE[rgb.g] );
|
||||
rgb.b = pgm_read_byte( &CIE1931_CURVE[rgb.b] );
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
55
quantum/color.h
Normal file
55
quantum/color.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
*
|
||||
* 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 COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define PACKED __attribute__ ((__packed__))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack( push, 1 )
|
||||
#endif
|
||||
|
||||
typedef struct PACKED
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} RGB;
|
||||
|
||||
typedef struct PACKED
|
||||
{
|
||||
uint8_t h;
|
||||
uint8_t s;
|
||||
uint8_t v;
|
||||
} HSV;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack( pop )
|
||||
#endif
|
||||
|
||||
RGB hsv_to_rgb( HSV hsv );
|
||||
|
||||
#endif // COLOR_H
|
@ -202,6 +202,9 @@ bool process_record_quantum(keyrecord_t *record) {
|
||||
process_key_lock(&keycode, record) &&
|
||||
#endif
|
||||
process_record_kb(keycode, record) &&
|
||||
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
|
||||
process_rgb_matrix(keycode, record) &&
|
||||
#endif
|
||||
#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
|
||||
process_midi(keycode, record) &&
|
||||
#endif
|
||||
@ -279,7 +282,7 @@ bool process_record_quantum(keyrecord_t *record) {
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
|
||||
case RGB_TOG:
|
||||
if (record->event.pressed) {
|
||||
rgblight_toggle();
|
||||
@ -737,9 +740,14 @@ void matrix_init_quantum() {
|
||||
#ifdef AUDIO_ENABLE
|
||||
audio_init();
|
||||
#endif
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
rgb_matrix_init_drivers();
|
||||
#endif
|
||||
matrix_init_kb();
|
||||
}
|
||||
|
||||
// uint16_t rgb_matrix_task_counter = 0;
|
||||
|
||||
void matrix_scan_quantum() {
|
||||
#ifdef AUDIO_ENABLE
|
||||
matrix_scan_music();
|
||||
@ -757,6 +765,12 @@ void matrix_scan_quantum() {
|
||||
backlight_task();
|
||||
#endif
|
||||
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
// if (rgb_matrix_task_counter == 0)
|
||||
rgb_matrix_task();
|
||||
// rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % 5);
|
||||
#endif
|
||||
|
||||
matrix_scan_kb();
|
||||
}
|
||||
|
||||
@ -862,13 +876,14 @@ void backlight_set(uint8_t level)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BACKLIGHT_BREATHING
|
||||
#if defined(BACKLIGHT_BREATHING)
|
||||
breathing_intensity_default();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t backlight_tick = 0;
|
||||
|
||||
__attribute__ ((weak))
|
||||
void backlight_task(void) {
|
||||
#ifdef NO_BACKLIGHT_CLOCK
|
||||
if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
|
||||
@ -894,6 +909,23 @@ void backlight_task(void) {
|
||||
|
||||
#ifdef BACKLIGHT_BREATHING
|
||||
|
||||
|
||||
#ifdef NO_BACKLIGHT_CLOCK
|
||||
void breathing_enable(void) {}
|
||||
void breathing_pulse(void) {}
|
||||
void breathing_disable(void) {}
|
||||
void breathing_self_disable(void) {}
|
||||
void breathing_toggle(void) {}
|
||||
bool is_breathing(void) { return false; }
|
||||
void breathing_intensity_default(void) {}
|
||||
void breathing_intensity_set(uint8_t value) {}
|
||||
void breathing_speed_default(void) {}
|
||||
void breathing_speed_set(uint8_t value) {}
|
||||
void breathing_speed_inc(uint8_t value) {}
|
||||
void breathing_speed_dec(uint8_t value) {}
|
||||
void breathing_defaults(void) {}
|
||||
#else
|
||||
|
||||
#define BREATHING_NO_HALT 0
|
||||
#define BREATHING_HALT_OFF 1
|
||||
#define BREATHING_HALT_ON 2
|
||||
@ -1093,7 +1125,7 @@ ISR(TIMER1_COMPA_vect)
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // no clock
|
||||
|
||||
#endif // breathing
|
||||
|
||||
@ -1156,6 +1188,7 @@ void send_nibble(uint8_t number) {
|
||||
__attribute__((weak))
|
||||
uint16_t hex_to_keycode(uint8_t hex)
|
||||
{
|
||||
hex = hex & 0xF;
|
||||
if (hex == 0x0) {
|
||||
return KC_0;
|
||||
} else if (hex < 0xA) {
|
||||
|
@ -27,9 +27,15 @@
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
#include "backlight.h"
|
||||
#endif
|
||||
#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
|
||||
#include "rgb.h"
|
||||
#endif
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#include "rgblight.h"
|
||||
#endif
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
#include "rgb_matrix.h"
|
||||
#endif
|
||||
#include "action_layer.h"
|
||||
#include "eeconfig.h"
|
||||
#include <stddef.h>
|
||||
|
47
quantum/rgb.h
Normal file
47
quantum/rgb.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RGB_H
|
||||
#define RGB_H
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_toggle(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_step(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_step_reverse(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_increase_hue(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_decrease_hue(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_increase_sat(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_decrease_sat(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_increase_val(void) {};
|
||||
|
||||
__attribute__((weak))
|
||||
void rgblight_decrease_val(void) {};
|
||||
|
||||
#endif
|
883
quantum/rgb_matrix.c
Normal file
883
quantum/rgb_matrix.c
Normal file
@ -0,0 +1,883 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "rgb_matrix.h"
|
||||
#include <avr/io.h>
|
||||
#include "TWIlib.h"
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "progmem.h"
|
||||
#include "config.h"
|
||||
#include "eeprom.h"
|
||||
#include "lufa.h"
|
||||
#include <math.h>
|
||||
|
||||
rgb_config_t rgb_matrix_config;
|
||||
|
||||
#ifndef RGB_DISABLE_AFTER_TIMEOUT
|
||||
#define RGB_DISABLE_AFTER_TIMEOUT 0
|
||||
#endif
|
||||
|
||||
#ifndef RGB_DISABLE_WHEN_USB_SUSPENDED
|
||||
#define RGB_DISABLE_WHEN_USB_SUSPENDED false
|
||||
#endif
|
||||
|
||||
#ifndef EECONFIG_RGB_MATRIX
|
||||
#define EECONFIG_RGB_MATRIX EECONFIG_RGBLIGHT
|
||||
#endif
|
||||
|
||||
bool g_suspend_state = false;
|
||||
|
||||
// Global tick at 20 Hz
|
||||
uint32_t g_tick = 0;
|
||||
|
||||
// Ticks since this key was last hit.
|
||||
uint8_t g_key_hit[DRIVER_LED_TOTAL];
|
||||
|
||||
// Ticks since any key was last hit.
|
||||
uint32_t g_any_key_hit = 0;
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265
|
||||
#endif
|
||||
|
||||
uint32_t eeconfig_read_rgb_matrix(void) {
|
||||
return eeprom_read_dword(EECONFIG_RGB_MATRIX);
|
||||
}
|
||||
void eeconfig_update_rgb_matrix(uint32_t val) {
|
||||
eeprom_update_dword(EECONFIG_RGB_MATRIX, val);
|
||||
}
|
||||
void eeconfig_update_rgb_matrix_default(void) {
|
||||
dprintf("eeconfig_update_rgb_matrix_default\n");
|
||||
rgb_matrix_config.enable = 1;
|
||||
rgb_matrix_config.mode = RGB_MATRIX_CYCLE_LEFT_RIGHT;
|
||||
rgb_matrix_config.hue = 0;
|
||||
rgb_matrix_config.sat = 255;
|
||||
rgb_matrix_config.val = 255;
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
void eeconfig_debug_rgb_matrix(void) {
|
||||
dprintf("rgb_matrix_config eprom\n");
|
||||
dprintf("rgb_matrix_config.enable = %d\n", rgb_matrix_config.enable);
|
||||
dprintf("rgb_matrix_config.mode = %d\n", rgb_matrix_config.mode);
|
||||
dprintf("rgb_matrix_config.hue = %d\n", rgb_matrix_config.hue);
|
||||
dprintf("rgb_matrix_config.sat = %d\n", rgb_matrix_config.sat);
|
||||
dprintf("rgb_matrix_config.val = %d\n", rgb_matrix_config.val);
|
||||
}
|
||||
|
||||
// Last led hit
|
||||
#define LED_HITS_TO_REMEMBER 8
|
||||
uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255};
|
||||
uint8_t g_last_led_count = 0;
|
||||
|
||||
void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led_i, uint8_t *led_count) {
|
||||
rgb_led led;
|
||||
*led_count = 0;
|
||||
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
// map_index_to_led(i, &led);
|
||||
led = g_rgb_leds[i];
|
||||
if (row == led.matrix_co.row && column == led.matrix_co.col) {
|
||||
led_i[*led_count] = i;
|
||||
(*led_count)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rgb_matrix_update_pwm_buffers(void) {
|
||||
IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
|
||||
IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
|
||||
}
|
||||
|
||||
void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) {
|
||||
IS31FL3731_set_color( index, red, green, blue );
|
||||
}
|
||||
|
||||
void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) {
|
||||
IS31FL3731_set_color_all( red, green, blue );
|
||||
}
|
||||
|
||||
|
||||
bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
|
||||
if ( record->event.pressed ) {
|
||||
uint8_t led[8], led_count;
|
||||
map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count);
|
||||
if (led_count > 0) {
|
||||
for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) {
|
||||
g_last_led_hit[i - 1] = g_last_led_hit[i - 2];
|
||||
}
|
||||
g_last_led_hit[0] = led[0];
|
||||
g_last_led_count = MIN(LED_HITS_TO_REMEMBER, g_last_led_count + 1);
|
||||
}
|
||||
for(uint8_t i = 0; i < led_count; i++)
|
||||
g_key_hit[led[i]] = 0;
|
||||
g_any_key_hit = 0;
|
||||
} else {
|
||||
#ifdef RGB_MATRIX_KEYRELEASES
|
||||
uint8_t led[8], led_count;
|
||||
map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count);
|
||||
for(uint8_t i = 0; i < led_count; i++)
|
||||
g_key_hit[led[i]] = 255;
|
||||
|
||||
g_any_key_hit = 255;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void rgb_matrix_set_suspend_state(bool state) {
|
||||
g_suspend_state = state;
|
||||
}
|
||||
|
||||
void rgb_matrix_test(void) {
|
||||
// Mask out bits 4 and 5
|
||||
// This 2-bit value will stay the same for 16 ticks.
|
||||
switch ( (g_tick & 0x30) >> 4 )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
rgb_matrix_set_color_all( 20, 0, 0 );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
rgb_matrix_set_color_all( 0, 20, 0 );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
rgb_matrix_set_color_all( 0, 0, 20 );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
rgb_matrix_set_color_all( 20, 20, 20 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This tests the LEDs
|
||||
// Note that it will change the LED control registers
|
||||
// in the LED drivers, and leave them in an invalid
|
||||
// state for other backlight effects.
|
||||
// ONLY USE THIS FOR TESTING LEDS!
|
||||
void rgb_matrix_single_LED_test(void) {
|
||||
static uint8_t color = 0; // 0,1,2 for R,G,B
|
||||
static uint8_t row = 0;
|
||||
static uint8_t column = 0;
|
||||
|
||||
static uint8_t tick = 0;
|
||||
tick++;
|
||||
|
||||
if ( tick > 2 )
|
||||
{
|
||||
tick = 0;
|
||||
column++;
|
||||
}
|
||||
if ( column > MATRIX_COLS )
|
||||
{
|
||||
column = 0;
|
||||
row++;
|
||||
}
|
||||
if ( row > MATRIX_ROWS )
|
||||
{
|
||||
row = 0;
|
||||
color++;
|
||||
}
|
||||
if ( color > 2 )
|
||||
{
|
||||
color = 0;
|
||||
}
|
||||
|
||||
uint8_t led[8], led_count;
|
||||
map_row_column_to_led(row,column,led,&led_count);
|
||||
for(uint8_t i = 0; i < led_count; i++) {
|
||||
rgb_matrix_set_color_all( 40, 40, 40 );
|
||||
rgb_matrix_test_led( led[i], color==0, color==1, color==2 );
|
||||
}
|
||||
}
|
||||
|
||||
// All LEDs off
|
||||
void rgb_matrix_all_off(void) {
|
||||
rgb_matrix_set_color_all( 0, 0, 0 );
|
||||
}
|
||||
|
||||
static HSV current_solid_color;
|
||||
|
||||
// Solid color
|
||||
void rgb_matrix_solid_color(void) {
|
||||
if (current_solid_color.h != rgb_matrix_config.hue &&
|
||||
current_solid_color.s != rgb_matrix_config.sat &&
|
||||
current_solid_color.v != rgb_matrix_config.val) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color_all( rgb.r, rgb.g, rgb.b );
|
||||
current_solid_color.h = hsv.h;
|
||||
current_solid_color.s = hsv.s;
|
||||
current_solid_color.v = hsv.v;
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_solid_reactive(void) {
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
uint16_t offset2 = g_key_hit[i]<<2;
|
||||
offset2 = (offset2<=130) ? (130-offset2) : 0;
|
||||
|
||||
HSV hsv = { .h = rgb_matrix_config.hue+offset2, .s = 255, .v = rgb_matrix_config.val };
|
||||
RGB rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
|
||||
// alphas = color1, mods = color2
|
||||
void rgb_matrix_alphas_mods(void) {
|
||||
|
||||
RGB rgb1 = hsv_to_rgb( (HSV){ .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val } );
|
||||
RGB rgb2 = hsv_to_rgb( (HSV){ .h = (rgb_matrix_config.hue + 180) % 360, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val } );
|
||||
|
||||
rgb_led led;
|
||||
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
if ( led.matrix_co.raw < 0xFF ) {
|
||||
if ( led.modifier )
|
||||
{
|
||||
rgb_matrix_set_color( i, rgb2.r, rgb2.g, rgb2.b );
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb_matrix_set_color( i, rgb1.r, rgb1.g, rgb1.b );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_gradient_up_down(void) {
|
||||
int16_t h1 = rgb_matrix_config.hue;
|
||||
int16_t h2 = (rgb_matrix_config.hue + 180) % 360;
|
||||
int16_t deltaH = h2 - h1;
|
||||
|
||||
// Take the shortest path between hues
|
||||
if ( deltaH > 127 )
|
||||
{
|
||||
deltaH -= 256;
|
||||
}
|
||||
else if ( deltaH < -127 )
|
||||
{
|
||||
deltaH += 256;
|
||||
}
|
||||
// Divide delta by 4, this gives the delta per row
|
||||
deltaH /= 4;
|
||||
|
||||
int16_t s1 = rgb_matrix_config.sat;
|
||||
int16_t s2 = rgb_matrix_config.hue;
|
||||
int16_t deltaS = ( s2 - s1 ) / 4;
|
||||
|
||||
HSV hsv = { .h = 0, .s = 255, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
Point point;
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
// map_led_to_point( i, &point );
|
||||
point = g_rgb_leds[i].point;
|
||||
// The y range will be 0..64, map this to 0..4
|
||||
uint8_t y = (point.y>>4);
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
hsv.h = rgb_matrix_config.hue + ( deltaH * y );
|
||||
hsv.s = rgb_matrix_config.sat + ( deltaS * y );
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_raindrops(bool initialize) {
|
||||
int16_t h1 = rgb_matrix_config.hue;
|
||||
int16_t h2 = (rgb_matrix_config.hue + 180) % 360;
|
||||
int16_t deltaH = h2 - h1;
|
||||
deltaH /= 4;
|
||||
|
||||
// Take the shortest path between hues
|
||||
if ( deltaH > 127 )
|
||||
{
|
||||
deltaH -= 256;
|
||||
}
|
||||
else if ( deltaH < -127 )
|
||||
{
|
||||
deltaH += 256;
|
||||
}
|
||||
|
||||
int16_t s1 = rgb_matrix_config.sat;
|
||||
int16_t s2 = rgb_matrix_config.sat;
|
||||
int16_t deltaS = ( s2 - s1 ) / 4;
|
||||
|
||||
HSV hsv;
|
||||
RGB rgb;
|
||||
|
||||
// Change one LED every tick
|
||||
uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % DRIVER_LED_TOTAL : 255;
|
||||
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
// If initialize, all get set to random colors
|
||||
// If not, all but one will stay the same as before.
|
||||
if ( initialize || i == led_to_change )
|
||||
{
|
||||
hsv.h = h1 + ( deltaH * ( rand() & 0x03 ) );
|
||||
hsv.s = s1 + ( deltaS * ( rand() & 0x03 ) );
|
||||
// Override brightness with global brightness control
|
||||
hsv.v = rgb_matrix_config.val;
|
||||
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_cycle_all(void) {
|
||||
uint8_t offset = g_tick & 0xFF;
|
||||
|
||||
rgb_led led;
|
||||
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
// map_index_to_led(i, &led);
|
||||
led = g_rgb_leds[i];
|
||||
if (led.matrix_co.raw < 0xFF) {
|
||||
uint16_t offset2 = g_key_hit[i]<<2;
|
||||
offset2 = (offset2<=63) ? (63-offset2) : 0;
|
||||
|
||||
HSV hsv = { .h = offset+offset2, .s = 255, .v = rgb_matrix_config.val };
|
||||
RGB rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_cycle_left_right(void) {
|
||||
uint8_t offset = g_tick & 0xFF;
|
||||
HSV hsv = { .h = 0, .s = 255, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
Point point;
|
||||
rgb_led led;
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
// map_index_to_led(i, &led);
|
||||
led = g_rgb_leds[i];
|
||||
if (led.matrix_co.raw < 0xFF) {
|
||||
uint16_t offset2 = g_key_hit[i]<<2;
|
||||
offset2 = (offset2<=63) ? (63-offset2) : 0;
|
||||
|
||||
// map_led_to_point( i, &point );
|
||||
point = g_rgb_leds[i].point;
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
hsv.h = point.x + offset + offset2;
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_cycle_up_down(void) {
|
||||
uint8_t offset = g_tick & 0xFF;
|
||||
HSV hsv = { .h = 0, .s = 255, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
Point point;
|
||||
rgb_led led;
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
// map_index_to_led(i, &led);
|
||||
led = g_rgb_leds[i];
|
||||
if (led.matrix_co.raw < 0xFF) {
|
||||
uint16_t offset2 = g_key_hit[i]<<2;
|
||||
offset2 = (offset2<=63) ? (63-offset2) : 0;
|
||||
|
||||
// map_led_to_point( i, &point );
|
||||
point = g_rgb_leds[i].point;
|
||||
// Relies on hue being 8-bit and wrapping
|
||||
hsv.h = point.y + offset + offset2;
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rgb_matrix_dual_beacon(void) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
rgb_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
hsv.h = ((led.point.y - 32.0)* cos(g_tick * PI / 128) / 32 + (led.point.x - 112.0) * sin(g_tick * PI / 128) / (112)) * (180) + rgb_matrix_config.hue;
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_rainbow_beacon(void) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
rgb_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
hsv.h = 1.5 * (led.point.y - 32.0)* cos(g_tick * PI / 128) + 1.5 * (led.point.x - 112.0) * sin(g_tick * PI / 128) + rgb_matrix_config.hue;
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_rainbow_pinwheels(void) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
rgb_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
hsv.h = 2 * (led.point.y - 32.0)* cos(g_tick * PI / 128) + 2 * (66 - abs(led.point.x - 112.0)) * sin(g_tick * PI / 128) + rgb_matrix_config.hue;
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_rainbow_moving_chevron(void) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
rgb_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
// uint8_t r = g_tick;
|
||||
uint8_t r = 32;
|
||||
hsv.h = 1.5 * abs(led.point.y - 32.0)* sin(r * PI / 128) + 1.5 * (led.point.x - (g_tick / 256.0 * 224)) * cos(r * PI / 128) + rgb_matrix_config.hue;
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rgb_matrix_jellybean_raindrops( bool initialize ) {
|
||||
HSV hsv;
|
||||
RGB rgb;
|
||||
|
||||
// Change one LED every tick
|
||||
uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % DRIVER_LED_TOTAL : 255;
|
||||
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
// If initialize, all get set to random colors
|
||||
// If not, all but one will stay the same as before.
|
||||
if ( initialize || i == led_to_change )
|
||||
{
|
||||
hsv.h = rand() & 0xFF;
|
||||
hsv.s = rand() & 0xFF;
|
||||
// Override brightness with global brightness control
|
||||
hsv.v = rgb_matrix_config.val;
|
||||
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rgb_matrix_multisplash(void) {
|
||||
// if (g_any_key_hit < 0xFF) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
rgb_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
uint16_t c = 0, d = 0;
|
||||
rgb_led last_led;
|
||||
// if (g_last_led_count) {
|
||||
for (uint8_t last_i = 0; last_i < g_last_led_count; last_i++) {
|
||||
last_led = g_rgb_leds[g_last_led_hit[last_i]];
|
||||
uint16_t dist = (uint16_t)sqrt(pow(led.point.x - last_led.point.x, 2) + pow(led.point.y - last_led.point.y, 2));
|
||||
uint16_t effect = (g_key_hit[g_last_led_hit[last_i]] << 2) - dist;
|
||||
c += MIN(MAX(effect, 0), 255);
|
||||
d += 255 - MIN(MAX(effect, 0), 255);
|
||||
}
|
||||
// } else {
|
||||
// d = 255;
|
||||
// }
|
||||
hsv.h = (rgb_matrix_config.hue + c) % 256;
|
||||
hsv.v = MAX(MIN(d, 255), 0);
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
// } else {
|
||||
// rgb_matrix_set_color_all( 0, 0, 0 );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void rgb_matrix_splash(void) {
|
||||
g_last_led_count = MIN(g_last_led_count, 1);
|
||||
rgb_matrix_multisplash();
|
||||
}
|
||||
|
||||
|
||||
void rgb_matrix_solid_multisplash(void) {
|
||||
// if (g_any_key_hit < 0xFF) {
|
||||
HSV hsv = { .h = rgb_matrix_config.hue, .s = rgb_matrix_config.sat, .v = rgb_matrix_config.val };
|
||||
RGB rgb;
|
||||
rgb_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_rgb_leds[i];
|
||||
uint16_t d = 0;
|
||||
rgb_led last_led;
|
||||
// if (g_last_led_count) {
|
||||
for (uint8_t last_i = 0; last_i < g_last_led_count; last_i++) {
|
||||
last_led = g_rgb_leds[g_last_led_hit[last_i]];
|
||||
uint16_t dist = (uint16_t)sqrt(pow(led.point.x - last_led.point.x, 2) + pow(led.point.y - last_led.point.y, 2));
|
||||
uint16_t effect = (g_key_hit[g_last_led_hit[last_i]] << 2) - dist;
|
||||
d += 255 - MIN(MAX(effect, 0), 255);
|
||||
}
|
||||
// } else {
|
||||
// d = 255;
|
||||
// }
|
||||
hsv.v = MAX(MIN(d, 255), 0);
|
||||
rgb = hsv_to_rgb( hsv );
|
||||
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
}
|
||||
// } else {
|
||||
// rgb_matrix_set_color_all( 0, 0, 0 );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void rgb_matrix_solid_splash(void) {
|
||||
g_last_led_count = MIN(g_last_led_count, 1);
|
||||
rgb_matrix_solid_multisplash();
|
||||
}
|
||||
|
||||
|
||||
// Needs eeprom access that we don't have setup currently
|
||||
|
||||
void rgb_matrix_custom(void) {
|
||||
// HSV hsv;
|
||||
// RGB rgb;
|
||||
// for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
// {
|
||||
// backlight_get_key_color(i, &hsv);
|
||||
// // Override brightness with global brightness control
|
||||
// hsv.v = rgb_matrix_config.val;
|
||||
// rgb = hsv_to_rgb( hsv );
|
||||
// rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
|
||||
// }
|
||||
}
|
||||
|
||||
void rgb_matrix_task(void) {
|
||||
if (!rgb_matrix_config.enable) {
|
||||
rgb_matrix_all_off();
|
||||
return;
|
||||
}
|
||||
// delay 1 second before driving LEDs or doing anything else
|
||||
static uint8_t startup_tick = 0;
|
||||
if ( startup_tick < 20 ) {
|
||||
startup_tick++;
|
||||
return;
|
||||
}
|
||||
|
||||
g_tick++;
|
||||
|
||||
if ( g_any_key_hit < 0xFFFFFFFF ) {
|
||||
g_any_key_hit++;
|
||||
}
|
||||
|
||||
for ( int led = 0; led < DRIVER_LED_TOTAL; led++ ) {
|
||||
if ( g_key_hit[led] < 255 ) {
|
||||
if (g_key_hit[led] == 254)
|
||||
g_last_led_count = MAX(g_last_led_count - 1, 0);
|
||||
g_key_hit[led]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Factory default magic value
|
||||
if ( rgb_matrix_config.mode == 255 ) {
|
||||
rgb_matrix_test();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ideally we would also stop sending zeros to the LED driver PWM buffers
|
||||
// while suspended and just do a software shutdown. This is a cheap hack for now.
|
||||
bool suspend_backlight = ((g_suspend_state && RGB_DISABLE_WHEN_USB_SUSPENDED) ||
|
||||
(RGB_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20));
|
||||
uint8_t effect = suspend_backlight ? 0 : rgb_matrix_config.mode;
|
||||
|
||||
// Keep track of the effect used last time,
|
||||
// detect change in effect, so each effect can
|
||||
// have an optional initialization.
|
||||
static uint8_t effect_last = 255;
|
||||
bool initialize = effect != effect_last;
|
||||
effect_last = effect;
|
||||
|
||||
// this gets ticked at 20 Hz.
|
||||
// each effect can opt to do calculations
|
||||
// and/or request PWM buffer updates.
|
||||
switch ( effect ) {
|
||||
case RGB_MATRIX_SOLID_COLOR:
|
||||
rgb_matrix_solid_color();
|
||||
break;
|
||||
case RGB_MATRIX_SOLID_REACTIVE:
|
||||
rgb_matrix_solid_reactive();
|
||||
break;
|
||||
case RGB_MATRIX_ALPHAS_MODS:
|
||||
rgb_matrix_alphas_mods();
|
||||
break;
|
||||
case RGB_MATRIX_DUAL_BEACON:
|
||||
rgb_matrix_dual_beacon();
|
||||
break;
|
||||
case RGB_MATRIX_GRADIENT_UP_DOWN:
|
||||
rgb_matrix_gradient_up_down();
|
||||
break;
|
||||
case RGB_MATRIX_RAINDROPS:
|
||||
rgb_matrix_raindrops( initialize );
|
||||
break;
|
||||
case RGB_MATRIX_CYCLE_ALL:
|
||||
rgb_matrix_cycle_all();
|
||||
break;
|
||||
case RGB_MATRIX_CYCLE_LEFT_RIGHT:
|
||||
rgb_matrix_cycle_left_right();
|
||||
break;
|
||||
case RGB_MATRIX_CYCLE_UP_DOWN:
|
||||
rgb_matrix_cycle_up_down();
|
||||
break;
|
||||
case RGB_MATRIX_RAINBOW_BEACON:
|
||||
rgb_matrix_rainbow_beacon();
|
||||
break;
|
||||
case RGB_MATRIX_RAINBOW_PINWHEELS:
|
||||
rgb_matrix_rainbow_pinwheels();
|
||||
break;
|
||||
case RGB_MATRIX_RAINBOW_MOVING_CHEVRON:
|
||||
rgb_matrix_rainbow_moving_chevron();
|
||||
break;
|
||||
case RGB_MATRIX_JELLYBEAN_RAINDROPS:
|
||||
rgb_matrix_jellybean_raindrops( initialize );
|
||||
break;
|
||||
#ifdef RGB_MATRIX_KEYPRESSES
|
||||
case RGB_MATRIX_SPLASH:
|
||||
rgb_matrix_splash();
|
||||
break;
|
||||
case RGB_MATRIX_MULTISPLASH:
|
||||
rgb_matrix_multisplash();
|
||||
break;
|
||||
case RGB_MATRIX_SOLID_SPLASH:
|
||||
rgb_matrix_solid_splash();
|
||||
break;
|
||||
case RGB_MATRIX_SOLID_MULTISPLASH:
|
||||
rgb_matrix_solid_multisplash();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
rgb_matrix_custom();
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! suspend_backlight ) {
|
||||
rgb_matrix_indicators();
|
||||
}
|
||||
|
||||
rgb_matrix_update_pwm_buffers();
|
||||
}
|
||||
|
||||
void rgb_matrix_indicators(void) {
|
||||
rgb_matrix_indicators_kb();
|
||||
rgb_matrix_indicators_user();
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void rgb_matrix_indicators_kb(void) {}
|
||||
|
||||
__attribute__((weak))
|
||||
void rgb_matrix_indicators_user(void) {}
|
||||
|
||||
|
||||
// void rgb_matrix_set_indicator_index( uint8_t *index, uint8_t row, uint8_t column )
|
||||
// {
|
||||
// if ( row >= MATRIX_ROWS )
|
||||
// {
|
||||
// // Special value, 255=none, 254=all
|
||||
// *index = row;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // This needs updated to something like
|
||||
// // uint8_t led[8], led_count;
|
||||
// // map_row_column_to_led(row,column,led,&led_count);
|
||||
// // for(uint8_t i = 0; i < led_count; i++)
|
||||
// map_row_column_to_led( row, column, index );
|
||||
// }
|
||||
// }
|
||||
|
||||
void rgb_matrix_init_drivers(void) {
|
||||
//sei();
|
||||
|
||||
// Initialize TWI
|
||||
TWIInit();
|
||||
IS31FL3731_init( DRIVER_ADDR_1 );
|
||||
IS31FL3731_init( DRIVER_ADDR_2 );
|
||||
|
||||
for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) {
|
||||
bool enabled = true;
|
||||
// This only caches it for later
|
||||
IS31FL3731_set_led_control_register( index, enabled, enabled, enabled );
|
||||
}
|
||||
// This actually updates the LED drivers
|
||||
IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
|
||||
|
||||
// TODO: put the 1 second startup delay here?
|
||||
|
||||
// clear the key hits
|
||||
for ( int led=0; led<DRIVER_LED_TOTAL; led++ ) {
|
||||
g_key_hit[led] = 255;
|
||||
}
|
||||
|
||||
|
||||
if (!eeconfig_is_enabled()) {
|
||||
dprintf("rgb_matrix_init_drivers eeconfig is not enabled.\n");
|
||||
eeconfig_init();
|
||||
eeconfig_update_rgb_matrix_default();
|
||||
}
|
||||
rgb_matrix_config.raw = eeconfig_read_rgb_matrix();
|
||||
if (!rgb_matrix_config.mode) {
|
||||
dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n");
|
||||
eeconfig_update_rgb_matrix_default();
|
||||
rgb_matrix_config.raw = eeconfig_read_rgb_matrix();
|
||||
}
|
||||
eeconfig_debug_rgb_matrix(); // display current eeprom values
|
||||
}
|
||||
|
||||
// Deals with the messy details of incrementing an integer
|
||||
uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
|
||||
int16_t new_value = value;
|
||||
new_value += step;
|
||||
return MIN( MAX( new_value, min ), max );
|
||||
}
|
||||
|
||||
uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
|
||||
int16_t new_value = value;
|
||||
new_value -= step;
|
||||
return MIN( MAX( new_value, min ), max );
|
||||
}
|
||||
|
||||
// void *backlight_get_custom_key_color_eeprom_address( uint8_t led )
|
||||
// {
|
||||
// // 3 bytes per color
|
||||
// return EECONFIG_RGB_MATRIX + ( led * 3 );
|
||||
// }
|
||||
|
||||
// void backlight_get_key_color( uint8_t led, HSV *hsv )
|
||||
// {
|
||||
// void *address = backlight_get_custom_key_color_eeprom_address( led );
|
||||
// hsv->h = eeprom_read_byte(address);
|
||||
// hsv->s = eeprom_read_byte(address+1);
|
||||
// hsv->v = eeprom_read_byte(address+2);
|
||||
// }
|
||||
|
||||
// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv )
|
||||
// {
|
||||
// uint8_t led[8], led_count;
|
||||
// map_row_column_to_led(row,column,led,&led_count);
|
||||
// for(uint8_t i = 0; i < led_count; i++) {
|
||||
// if ( led[i] < DRIVER_LED_TOTAL )
|
||||
// {
|
||||
// void *address = backlight_get_custom_key_color_eeprom_address(led[i]);
|
||||
// eeprom_update_byte(address, hsv.h);
|
||||
// eeprom_update_byte(address+1, hsv.s);
|
||||
// eeprom_update_byte(address+2, hsv.v);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue ) {
|
||||
for ( int i=0; i<DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
if ( i == index )
|
||||
{
|
||||
IS31FL3731_set_led_control_register( i, red, green, blue );
|
||||
}
|
||||
else
|
||||
{
|
||||
IS31FL3731_set_led_control_register( i, false, false, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rgb_matrix_get_tick(void) {
|
||||
return g_tick;
|
||||
}
|
||||
|
||||
void rgblight_toggle(void) {
|
||||
rgb_matrix_config.enable ^= 1;
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_step(void) {
|
||||
rgb_matrix_config.mode++;
|
||||
if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX)
|
||||
rgb_matrix_config.mode = 1;
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_step_reverse(void) {
|
||||
rgb_matrix_config.mode--;
|
||||
if (rgb_matrix_config.mode <= 1)
|
||||
rgb_matrix_config.mode = (RGB_MATRIX_EFFECT_MAX - 1);
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_increase_hue(void) {
|
||||
rgb_matrix_config.hue = increment( rgb_matrix_config.hue, 8, 0, 255 );
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_decrease_hue(void) {
|
||||
rgb_matrix_config.hue = decrement( rgb_matrix_config.hue, 8, 0, 255 );
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_increase_sat(void) {
|
||||
rgb_matrix_config.sat = increment( rgb_matrix_config.sat, 8, 0, 255 );
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_decrease_sat(void) {
|
||||
rgb_matrix_config.sat = decrement( rgb_matrix_config.sat, 8, 0, 255 );
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_increase_val(void) {
|
||||
rgb_matrix_config.val = increment( rgb_matrix_config.val, 8, 0, 255 );
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_decrease_val(void) {
|
||||
rgb_matrix_config.val = decrement( rgb_matrix_config.val, 8, 0, 255 );
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
void rgblight_mode(uint8_t mode) {
|
||||
rgb_matrix_config.mode = 1;
|
||||
eeconfig_update_rgb_matrix(rgb_matrix_config.raw);
|
||||
}
|
||||
|
||||
uint32_t rgblight_get_mode(void) {
|
||||
return rgb_matrix_config.mode;
|
||||
}
|
135
quantum/rgb_matrix.h
Normal file
135
quantum/rgb_matrix.h
Normal file
@ -0,0 +1,135 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2017 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RGB_MATRIX_H
|
||||
#define RGB_MATRIX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "color.h"
|
||||
#include "is31fl3731.h"
|
||||
#include "quantum.h"
|
||||
|
||||
typedef struct Point {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} __attribute__((packed)) Point;
|
||||
|
||||
typedef struct rgb_led {
|
||||
union {
|
||||
uint8_t raw;
|
||||
struct {
|
||||
uint8_t row:4; // 16 max
|
||||
uint8_t col:4; // 16 max
|
||||
};
|
||||
} matrix_co;
|
||||
Point point;
|
||||
uint8_t modifier:1;
|
||||
} __attribute__((packed)) rgb_led;
|
||||
|
||||
|
||||
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HSV color;
|
||||
uint8_t index;
|
||||
} rgb_indicator;
|
||||
|
||||
typedef union {
|
||||
uint32_t raw;
|
||||
struct {
|
||||
bool enable :1;
|
||||
uint8_t mode :6;
|
||||
uint16_t hue :9;
|
||||
uint8_t sat :8;
|
||||
uint8_t val :8;
|
||||
};
|
||||
} rgb_config_t;
|
||||
|
||||
enum rgb_matrix_effects {
|
||||
RGB_MATRIX_SOLID_COLOR = 1,
|
||||
RGB_MATRIX_SOLID_REACTIVE,
|
||||
RGB_MATRIX_ALPHAS_MODS,
|
||||
RGB_MATRIX_DUAL_BEACON,
|
||||
RGB_MATRIX_GRADIENT_UP_DOWN,
|
||||
RGB_MATRIX_RAINDROPS,
|
||||
RGB_MATRIX_CYCLE_ALL,
|
||||
RGB_MATRIX_CYCLE_LEFT_RIGHT,
|
||||
RGB_MATRIX_CYCLE_UP_DOWN,
|
||||
RGB_MATRIX_RAINBOW_BEACON,
|
||||
RGB_MATRIX_RAINBOW_PINWHEELS,
|
||||
RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
|
||||
RGB_MATRIX_JELLYBEAN_RAINDROPS,
|
||||
#ifdef RGB_MATRIX_KEYPRESSES
|
||||
RGB_MATRIX_SPLASH,
|
||||
RGB_MATRIX_MULTISPLASH,
|
||||
RGB_MATRIX_SOLID_SPLASH,
|
||||
RGB_MATRIX_SOLID_MULTISPLASH,
|
||||
#endif
|
||||
RGB_MATRIX_EFFECT_MAX
|
||||
};
|
||||
|
||||
void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
|
||||
|
||||
// This runs after another backlight effect and replaces
|
||||
// colors already set
|
||||
void rgb_matrix_indicators(void);
|
||||
void rgb_matrix_indicators_kb(void);
|
||||
void rgb_matrix_indicators_user(void);
|
||||
|
||||
void rgb_matrix_single_LED_test(void);
|
||||
|
||||
void rgb_matrix_init_drivers(void);
|
||||
|
||||
void rgb_matrix_set_suspend_state(bool state);
|
||||
void rgb_matrix_set_indicator_state(uint8_t state);
|
||||
|
||||
|
||||
void rgb_matrix_task(void);
|
||||
|
||||
// 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 rgb_matrix_update_pwm_buffers(void);
|
||||
|
||||
bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record);
|
||||
|
||||
void rgb_matrix_increase(void);
|
||||
void rgb_matrix_decrease(void);
|
||||
|
||||
// void *backlight_get_key_color_eeprom_address(uint8_t led);
|
||||
// void backlight_get_key_color( uint8_t led, HSV *hsv );
|
||||
// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv );
|
||||
|
||||
void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue );
|
||||
uint32_t rgb_matrix_get_tick(void);
|
||||
|
||||
void rgblight_toggle(void);
|
||||
void rgblight_step(void);
|
||||
void rgblight_step_reverse(void);
|
||||
void rgblight_increase_hue(void);
|
||||
void rgblight_decrease_hue(void);
|
||||
void rgblight_increase_sat(void);
|
||||
void rgblight_decrease_sat(void);
|
||||
void rgblight_increase_val(void);
|
||||
void rgblight_decrease_val(void);
|
||||
void rgblight_mode(uint8_t mode);
|
||||
uint32_t rgblight_get_mode(void);
|
||||
|
||||
#endif
|
@ -56,14 +56,20 @@
|
||||
* | Bootloader | 512B | Bootloader | 1KB
|
||||
* 0x7FFF +---------------+ 0x1FFFF +---------------+
|
||||
*/
|
||||
|
||||
#if !defined(BOOTLOADER_SIZE) && !defined(BOOTLOADER_START)
|
||||
#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE or BOOTLOADER_START in config.h.
|
||||
#endif
|
||||
|
||||
#ifndef BOOTLOADER_SIZE
|
||||
#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h.
|
||||
#define BOOTLOADER_SIZE 4096
|
||||
#endif
|
||||
|
||||
#define FLASH_SIZE (FLASHEND + 1L)
|
||||
#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE)
|
||||
|
||||
#ifndef BOOTLOADER_START
|
||||
#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Entering the Bootloader via Software
|
||||
|
@ -1,15 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# test force push
|
||||
#TRAVIS_COMMIT_RANGE="c287f1bfc5c8...81f62atc4c1d"
|
||||
|
||||
TRAVIS_COMMIT_MESSAGE="${TRAVIS_COMMIT_MESSAGE:-none}"
|
||||
TRAVIS_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE:-HEAD~1..HEAD}"
|
||||
MAKE_ALL="make all:default AUTOGEN=\"true\""
|
||||
|
||||
if [[ "$TRAVIS_COMMIT_MESSAGE" != *"[skip build]"* ]] ; then
|
||||
exit_code=0
|
||||
git diff --name-only -n 1 ${TRAVIS_COMMIT_RANGE}
|
||||
if [ $? -eq 128 ]; then
|
||||
echo "Making default keymaps for all keyboards"
|
||||
eval $MAKE_ALL
|
||||
: $((exit_code = $exit_code + $?))
|
||||
else
|
||||
NEFM=$(git diff --name-only -n 1 ${TRAVIS_COMMIT_RANGE} | grep -Ev '^(keyboards/)' | grep -Ev '^(docs/)' | wc -l)
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ $NEFM -gt 0 -o "$BRANCH" = "master" ]; then
|
||||
echo "Making all keymaps for all keyboards"
|
||||
make all:default AUTOGEN="true"
|
||||
echo "Making default keymaps for all keyboards"
|
||||
eval $MAKE_ALL
|
||||
: $((exit_code = $exit_code + $?))
|
||||
else
|
||||
MKB=$(git diff --name-only -n 1 ${TRAVIS_COMMIT_RANGE} | grep -oP '(?<=keyboards\/)([a-zA-Z0-9_\/]+)(?=\/)' | sort -u)
|
||||
@ -32,5 +42,6 @@ if [[ "$TRAVIS_COMMIT_MESSAGE" != *"[skip build]"* ]] ; then
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
exit $exit_code
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user