Add modifier state to the split keyboard transport (#10400)
* Add modifier state to the split transport This adds modifier state to the i2c and serial transport for split keyboards. The purpose of this is to allow e.g. displaying modifier state on the slave side of a split keyboard on an oled. This adds one byte to the data transferred between halves. This also fixes a missing ifdef guard for BLACKLIGHT_ENABLE. Break modifiers into real/weak/oneshot Fix incorrect slave serial mod setting Fix typo in serial weal mod setter Fix build errors for the I2C code that I introduced Code cleanup and formatting per project preferences Correctly get oneshot mods Fix missing braces Remove unneeded ifdef guard Make the added state transport optional Add documentation for the new define to enable this feature Fix stray grave mark * Fix error introduced in conflict resolution
This commit is contained in:
parent
9c205d4a29
commit
5e2b53541b
2 changed files with 78 additions and 0 deletions
|
@ -181,6 +181,16 @@ If you're having issues with serial communication, you can change this value, as
|
||||||
* **`4`**: about 26kbps
|
* **`4`**: about 26kbps
|
||||||
* **`5`**: about 20kbps
|
* **`5`**: about 20kbps
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SPLIT_MODS_ENABLE
|
||||||
|
```
|
||||||
|
|
||||||
|
This enables transmitting modifier state (normal, weak and oneshot) to the non
|
||||||
|
primary side of the split keyboard. This adds a few bytes of data to the split
|
||||||
|
communication protocol and may impact the matrix scan speed when enabled.
|
||||||
|
The purpose of this feature is to support cosmetic use of modifer state (e.g.
|
||||||
|
displaying status on an OLED screen).
|
||||||
|
|
||||||
### Hardware Configuration Options
|
### Hardware Configuration Options
|
||||||
|
|
||||||
There are some settings that you may need to configure, based on how the hardware is set up.
|
There are some settings that you may need to configure, based on how the hardware is set up.
|
||||||
|
|
|
@ -32,7 +32,16 @@ typedef struct _I2C_slave_buffer_t {
|
||||||
uint32_t sync_timer;
|
uint32_t sync_timer;
|
||||||
# endif
|
# endif
|
||||||
matrix_row_t smatrix[ROWS_PER_HAND];
|
matrix_row_t smatrix[ROWS_PER_HAND];
|
||||||
|
# ifdef SPLIT_MODS_ENABLE
|
||||||
|
uint8_t real_mods;
|
||||||
|
uint8_t weak_mods;
|
||||||
|
# ifndef NO_ACTION_ONESHOT
|
||||||
|
uint8_t oneshot_mods;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# ifdef BACKLIGHT_ENABLE
|
||||||
uint8_t backlight_level;
|
uint8_t backlight_level;
|
||||||
|
# endif
|
||||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
||||||
rgblight_syncinfo_t rgblight_sync;
|
rgblight_syncinfo_t rgblight_sync;
|
||||||
# endif
|
# endif
|
||||||
|
@ -46,6 +55,10 @@ typedef struct _I2C_slave_buffer_t {
|
||||||
|
|
||||||
static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
|
static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
|
||||||
|
|
||||||
|
# define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, smatrix)
|
||||||
|
# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
|
||||||
|
# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
|
||||||
|
# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
|
||||||
# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
|
# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
|
||||||
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
|
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
|
||||||
# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
|
# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
|
||||||
|
@ -97,6 +110,31 @@ bool transport_master(matrix_row_t matrix[]) {
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef SPLIT_MODS_ENABLE
|
||||||
|
uint8_t real_mods = get_mods();
|
||||||
|
if (real_mods != i2c_buffer->real_mods) {
|
||||||
|
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) {
|
||||||
|
i2c_buffer->real_mods = real_mods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t weak_mods = get_weak_mods();
|
||||||
|
if (weak_mods != i2c_buffer->weak_mods) {
|
||||||
|
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) {
|
||||||
|
i2c_buffer->weak_mods = weak_mods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifndef NO_ACTION_ONESHOT
|
||||||
|
uint8_t oneshot_mods = get_oneshot_mods();
|
||||||
|
if (oneshot_mods != i2c_buffer->oneshot_mods) {
|
||||||
|
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) {
|
||||||
|
i2c_buffer->oneshot_mods = oneshot_mods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifndef DISABLE_SYNC_TIMER
|
# ifndef DISABLE_SYNC_TIMER
|
||||||
i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
|
i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
|
||||||
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
|
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
|
||||||
|
@ -131,6 +169,14 @@ void transport_slave(matrix_row_t matrix[]) {
|
||||||
# ifdef WPM_ENABLE
|
# ifdef WPM_ENABLE
|
||||||
set_current_wpm(i2c_buffer->current_wpm);
|
set_current_wpm(i2c_buffer->current_wpm);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef SPLIT_MODS_ENABLE
|
||||||
|
set_mods(i2c_buffer->real_mods);
|
||||||
|
set_weak_mods(i2c_buffer->weak_mods);
|
||||||
|
# ifndef NO_ACTION_ONESHOT
|
||||||
|
set_oneshot_mods(i2c_buffer->oneshot_mods);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void transport_master_init(void) { i2c_init(); }
|
void transport_master_init(void) { i2c_init(); }
|
||||||
|
@ -152,6 +198,13 @@ typedef struct _Serial_s2m_buffer_t {
|
||||||
} Serial_s2m_buffer_t;
|
} Serial_s2m_buffer_t;
|
||||||
|
|
||||||
typedef struct _Serial_m2s_buffer_t {
|
typedef struct _Serial_m2s_buffer_t {
|
||||||
|
# ifdef SPLIT_MODS_ENABLE
|
||||||
|
uint8_t real_mods;
|
||||||
|
uint8_t weak_mods;
|
||||||
|
# ifndef NO_ACTION_ONESHOT
|
||||||
|
uint8_t oneshot_mods;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
# ifndef DISABLE_SYNC_TIMER
|
# ifndef DISABLE_SYNC_TIMER
|
||||||
uint32_t sync_timer;
|
uint32_t sync_timer;
|
||||||
# endif
|
# endif
|
||||||
|
@ -268,6 +321,13 @@ bool transport_master(matrix_row_t matrix[]) {
|
||||||
serial_m2s_buffer.current_wpm = get_current_wpm();
|
serial_m2s_buffer.current_wpm = get_current_wpm();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef SPLIT_MODS_ENABLE
|
||||||
|
serial_m2s_buffer.real_mods = get_mods();
|
||||||
|
serial_m2s_buffer.weak_mods = get_weak_mods();
|
||||||
|
# ifndef NO_ACTION_ONESHOT
|
||||||
|
serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
# ifndef DISABLE_SYNC_TIMER
|
# ifndef DISABLE_SYNC_TIMER
|
||||||
serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
|
serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
|
||||||
# endif
|
# endif
|
||||||
|
@ -295,6 +355,14 @@ void transport_slave(matrix_row_t matrix[]) {
|
||||||
# ifdef WPM_ENABLE
|
# ifdef WPM_ENABLE
|
||||||
set_current_wpm(serial_m2s_buffer.current_wpm);
|
set_current_wpm(serial_m2s_buffer.current_wpm);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef SPLIT_MODS_ENABLE
|
||||||
|
set_mods(serial_m2s_buffer.real_mods);
|
||||||
|
set_weak_mods(serial_m2s_buffer.weak_mods);
|
||||||
|
# ifndef NO_ACTION_ONESHOT
|
||||||
|
set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue