Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change split_common to use RGBLIGHT_SPLIT #5509

Merged
merged 24 commits into from
Apr 19, 2019
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
aebddfc
add temporary pdhelix(Patched Helix) code
mtei Mar 25, 2019
c01656a
add I2C_slave_buffer_t to quantum/split_common/transport.c
mtei Mar 24, 2019
d35069f
temporary cherry-pick from #5020
mtei Mar 25, 2019
f6e8aeb
add post_config.h support to build_keyboard.mk
mtei Mar 27, 2019
1aa14c5
add quantum/rgblight_post_config.h, quantum/split_common/post_config.h
mtei Mar 27, 2019
57e124c
Change split_common's transport.c I2C to use the synchronization feat…
mtei Mar 27, 2019
07c33fc
Change split_common's transport.c serial to use the synchronization f…
mtei Mar 29, 2019
80118a6
test RGBLIGHT_SPLIT on keyboards/handwired/pdhelix
mtei Mar 29, 2019
dbbdfa3
Test End Revert "test RGBLIGHT_SPLIT on keyboards/handwired/pdhelix"
mtei Mar 29, 2019
4d7310f
Test End, Revert "temporary cherry-pick from #5020"
mtei Mar 29, 2019
c8d1c83
Test End, Revert "add temporary pdhelix(Patched Helix) code"
mtei Mar 29, 2019
647c0a9
temporarily cherry-pick from #5020 to see if it passes the travis-ci …
mtei Mar 25, 2019
6b77e60
Passed the travis-ci test. Revert "temporarily cherry-pick from #5020…
mtei Mar 29, 2019
35d6855
update docs/config_options.md
mtei Mar 29, 2019
c68ee60
update split_common/transport.c, improves maintainability of serial t…
mtei Mar 30, 2019
a3f7089
Merge branch 'master' into split_common-use-RGBLIGHT_SPLIT
mtei Apr 4, 2019
be48ca1
temporary cherry-pick from #5020
mtei Apr 4, 2019
89ad6eb
fix build fail keebio/iris/rev3:default
mtei Apr 6, 2019
21b43bc
fix build fail lets_split_eh/eh:default
mtei Apr 6, 2019
419f045
Revert "temporary cherry-pick from #5020"
mtei Apr 16, 2019
978d26a
temporary cherry-pick from #5020 (0.6.336)
mtei Apr 16, 2019
4c56c82
Revert "temporary cherry-pick from #5020 (0.6.336)"
mtei Apr 16, 2019
e5f59ad
Merge branch 'master' into split_common-use-RGBLIGHT_SPLIT
mtei Apr 16, 2019
fa28d10
temporary cherry-pick from #5020 (0.6.336)
mtei Apr 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions build_keyboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,23 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_1)/config.h)","")
CONFIG_H += $(KEYBOARD_PATH_1)/config.h
endif

POST_CONFIG_H :=
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required to work properly?

Eg, can the post_config stuff be moved so this isn't needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary.
It is necessary to prevent unnecessary dependencies between header files between modules in lower layers.

For example, quantum/split_common/transport.c needs to define SERIAL_USE_MULTI_TRANSACTION of serial when using RGBLIGHT_SPLIT.
It is not good to solve this with serial.h and rgblight.h.

ifneq ("$(wildcard $(KEYBOARD_PATH_1)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_1)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_2)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_3)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_4)/post_config.h
endif
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/post_config.h)","")
POST_CONFIG_H += $(KEYBOARD_PATH_5)/post_config.h
endif

# Save the defines and includes here, so we don't include any keymap specific ones
PROJECT_DEFS := $(OPT_DEFS)
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
Expand Down Expand Up @@ -355,6 +372,7 @@ ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
include $(VISUALIZER_PATH)/visualizer.mk
endif

CONFIG_H += $(POST_CONFIG_H)
ALL_CONFIGS := $(PROJECT_CONFIG) $(CONFIG_H)

OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
Expand Down
2 changes: 2 additions & 0 deletions common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ ifeq ($(strip $(UNICODE_COMMON)), yes)
endif

ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight_post_config.h
OPT_DEFS += -DRGBLIGHT_ENABLE
SRC += $(QUANTUM_DIR)/rgblight.c
CIE1931_CURVE = yes
Expand Down Expand Up @@ -305,6 +306,7 @@ ifneq ($(strip $(DEBOUNCE_TYPE)), custom)
endif

ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
POST_CONFIG_H += $(QUANTUM_DIR)/split_common/post_config.h
OPT_DEFS += -DSPLIT_KEYBOARD

# Include files used by all split keyboards
Expand Down
4 changes: 3 additions & 1 deletion docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,12 @@ If you define these options you will enable the associated feature, which may in
* run RGB animations
* `#define RGBLED_NUM 12`
* number of LEDs
* `#define RGBLIGHT_SPLIT`
* Needed if both halves of the board have RGB LEDs wired directly to the RGB output pin on the controllers instead of passing the output of the left half to the input of the right half
* `#define RGBLED_SPLIT { 6, 6 }`
* number of LEDs connected that are directly wired to `RGB_DI_PIN` on each half of a split keyboard
* First value indicates number of LEDs for left half, second value is for the right half
* Needed if both halves of the board have RGB LEDs wired directly to the RGB output pin on the controllers instead of passing the output of the left half to the input of the right half
* When RGBLED_SPLIT is defined, it is considered that RGBLIGHT_SPLIT is defined implicitly.
drashna marked this conversation as resolved.
Show resolved Hide resolved
* `#define RGBLIGHT_HUE_STEP 12`
* units to step when in/decreasing hue
* `#define RGBLIGHT_SAT_STEP 25`
Expand Down
5 changes: 5 additions & 0 deletions quantum/rgblight_post_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#if defined(RGBLED_SPLIT) && !defined(RGBLIGHT_SPLIT)
// When RGBLED_SPLIT is defined,
// it is considered that RGBLIGHT_SPLIT is defined implicitly.
#define RGBLIGHT_SPLIT
#endif
15 changes: 15 additions & 0 deletions quantum/split_common/post_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#if defined(USE_I2C) || defined(EH)
// When using I2C, using rgblight implicitly involves split support.
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)
#define RGBLIGHT_SPLIT
#endif

#else // use serial
// When using serial, the user must define RGBLIGHT_SPLIT explicitly
// in config.h as needed.
// see quantum/rgblight_post_config.h
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// When using serial and RGBLIGHT_SPLIT need separate transaction
#define SERIAL_USE_MULTI_TRANSACTION
#endif
#endif
132 changes: 91 additions & 41 deletions quantum/split_common/transport.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <string.h>
#include <stddef.h>

#include "config.h"
#include "matrix.h"
Expand All @@ -20,10 +21,19 @@ extern backlight_config_t backlight_config;
# include "i2c_master.h"
# include "i2c_slave.h"

# define I2C_BACKLIT_START 0x00
// Need 4 bytes for RGB (32 bit)
# define I2C_RGB_START 0x01
# define I2C_KEYMAP_START 0x05
typedef struct _I2C_slave_buffer_t {
uint8_t backlit_level;
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
rgblight_syncinfo_t rgblight_sync;
#endif
matrix_row_t smatrix[ROWS_PER_HAND];
} I2C_slave_buffer_t;

static I2C_slave_buffer_t * const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;

# define I2C_BACKLIT_START offsetof(I2C_slave_buffer_t, backlit_level)
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)

# define TIMEOUT 100

Expand All @@ -33,7 +43,7 @@ extern backlight_config_t backlight_config;

// Get rows from other half over i2c
bool transport_master(matrix_row_t matrix[]) {
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t), TIMEOUT);
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);

// write backlight info
# ifdef BACKLIGHT_ENABLE
Expand All @@ -46,12 +56,13 @@ bool transport_master(matrix_row_t matrix[]) {
}
# endif

# ifdef RGBLIGHT_ENABLE
static uint32_t prev_rgb = ~0;
uint32_t rgb = rgblight_read_dword();
if (rgb != prev_rgb) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgb, sizeof(rgb), TIMEOUT) >= 0) {
prev_rgb = rgb;
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
if (rgblight_get_change_flags()) {
rgblight_syncinfo_t rgblight_sync;
rgblight_get_syncinfo(&rgblight_sync);
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START,
(void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
rgblight_clear_change_flags();
}
}
# endif
Expand All @@ -61,17 +72,19 @@ bool transport_master(matrix_row_t matrix[]) {

void transport_slave(matrix_row_t matrix[]) {
// Copy matrix to I2C buffer
memcpy((void*)(i2c_slave_reg + I2C_KEYMAP_START), (void *)matrix, ROWS_PER_HAND * sizeof(matrix_row_t) );
memcpy((void*)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix));

// Read Backlight Info
# ifdef BACKLIGHT_ENABLE
backlight_set(i2c_slave_reg[I2C_BACKLIT_START]);
backlight_set(i2c_buffer->backlit_level);
# endif

# ifdef RGBLIGHT_ENABLE
uint32_t rgb = *(uint32_t *)(i2c_slave_reg + I2C_RGB_START);
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// Update the RGB with the new data
rgblight_update_dword(rgb);
if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
i2c_buffer->rgblight_sync.status.change_flags = 0;
}
# endif
}

Expand All @@ -92,41 +105,90 @@ typedef struct _Serial_m2s_buffer_t {
# ifdef BACKLIGHT_ENABLE
uint8_t backlight_level;
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
rgblight_config_t rgblight_config; // not yet use
//
// When MCUs on both sides drive their respective RGB LED chains,
// it is necessary to synchronize, so it is necessary to communicate RGB
// information. In that case, define RGBLED_SPLIT with info on the number
// of LEDs on each half.
//
// Otherwise, if the master side MCU drives both sides RGB LED chains,
// there is no need to communicate.
# endif
} Serial_m2s_buffer_t;

#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// When MCUs on both sides drive their respective RGB LED chains,
// it is necessary to synchronize, so it is necessary to communicate RGB
// information. In that case, define RGBLIGHT_SPLIT with info on the number
// of LEDs on each half.
//
// Otherwise, if the master side MCU drives both sides RGB LED chains,
// there is no need to communicate.

typedef struct _Serial_rgblight_t {
rgblight_syncinfo_t rgblight_sync;
} Serial_rgblight_t;

volatile Serial_rgblight_t serial_rgblight = {};
uint8_t volatile status_rgblight = 0;
#endif

volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
uint8_t volatile status0 = 0;

SSTD_t transactions[] = {
{
#define GET_SLAVE_MATRIX 0
(uint8_t *)&status0,
sizeof(serial_m2s_buffer),
(uint8_t *)&serial_m2s_buffer,
sizeof(serial_s2m_buffer),
(uint8_t *)&serial_s2m_buffer,
},
#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
#define PUT_RGBLIGHT 1
{
(uint8_t *)&status_rgblight,
sizeof(serial_rgblight),
(uint8_t *)&serial_rgblight,
0, NULL
},
#endif
};

void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }

void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }

#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)

// rgblight synchronization information communication.

void transport_rgblight_master(void) {
if (rgblight_get_change_flags()) {
rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
rgblight_clear_change_flags();
}
}
}

void transport_rgblight_slave(void) {
if (status_rgblight == TRANSACTION_ACCEPTED) {
rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync,
false);
status_rgblight = TRANSACTION_END;
}
}

#else
#define transport_rgblight_master()
#define transport_rgblight_slave()
#endif

bool transport_master(matrix_row_t matrix[]) {
if (soft_serial_transaction()) {
#ifndef SERIAL_USE_MULTI_TRANSACTION
if (soft_serial_transaction() != TRANSACTION_END) {
return false;
}
#else
transport_rgblight_master();
if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
return false;
}
#endif

// TODO: if MATRIX_COLS > 8 change to unpack()
for (int i = 0; i < ROWS_PER_HAND; ++i) {
Expand All @@ -138,30 +200,18 @@ bool transport_master(matrix_row_t matrix[]) {
serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
# endif

# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
static rgblight_config_t prev_rgb = {~0};
uint32_t rgb = rgblight_read_dword();
if (rgb != prev_rgb.raw) {
serial_m2s_buffer.rgblight_config.raw = rgb;
prev_rgb.raw = rgb;
}
# endif

return true;
}

void transport_slave(matrix_row_t matrix[]) {
transport_rgblight_slave();
// TODO: if MATRIX_COLS > 8 change to pack()
for (int i = 0; i < ROWS_PER_HAND; ++i) {
serial_s2m_buffer.smatrix[i] = matrix[i];
}
# ifdef BACKLIGHT_ENABLE
backlight_set(serial_m2s_buffer.backlight_level);
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
// Update RGB config with the new data
rgblight_update_dword(serial_m2s_buffer.rgblight_config.raw);
# endif
}

#endif