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

Enable sync of OLED/ST7565 display on/off state on Splits #13542

Merged
merged 2 commits into from
Aug 15, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
6 changes: 6 additions & 0 deletions docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,12 @@ There are a few different ways to set handedness for split keyboards (listed in
* `#define SPLIT_WPM_ENABLE`
* Ensures the current WPM is available on the slave when using the QMK-provided split transport.

* `#define SPLIT_OLED_ENABLE`
* Syncs the on/off state of the OLED between the halves.

* `#define SPLIT_ST7565_ENABLE`
* Syncs the on/off state of the ST7565 screen between the halves.

* `#define SPLIT_TRANSACTION_IDS_KB .....`
* `#define SPLIT_TRANSACTION_IDS_USER .....`
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard.md#custom-data-sync) for more information.
Expand Down
12 changes: 12 additions & 0 deletions docs/feature_split_keyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@ This enables transmitting modifier state (normal, weak and oneshot) to the non p

This enables transmitting the current WPM to the slave side of the split keyboard. The purpose of this feature is to support cosmetic use of WPM (e.g. displaying the current value on an OLED screen). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.

```c
#define SPLIT_OLED_ENABLE
```

This enables transmitting the current OLED on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing. This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.

```c
#define SPLIT_ST7565_ENABLE
```

This enables transmitting the current ST7565 on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing. This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.

### Custom data sync between sides :id=custom-data-sync

QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
Expand Down
8 changes: 8 additions & 0 deletions quantum/split_common/transaction_id_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ enum serial_transaction_id {
PUT_WPM,
#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)

#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)
PUT_OLED,
#endif // defined(WPM_ENABLE) && defined(SPLIT_OLED_ENABLE)

#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
PUT_ST7565,
#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
PUT_RPC_INFO,
PUT_RPC_REQ_DATA,
Expand Down
108 changes: 88 additions & 20 deletions quantum/split_common/transactions.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
{ &dummy, 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb }
#define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL)

#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0)
#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length)
#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0)
#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length)

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
// Forward-declare the RPC callback handlers
Expand Down Expand Up @@ -160,8 +160,8 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro
memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix));
}

# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers)
# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers)
# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers)
# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers)
# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix),

#else // SPLIT_TRANSPORT_MIRROR
Expand Down Expand Up @@ -238,8 +238,8 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
}
}

# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers)
# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers)
# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers)
# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers)
# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer),

#else // DISABLE_SYNC_TIMER
Expand Down Expand Up @@ -303,8 +303,8 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
set_split_host_keyboard_leds(split_shmem->led_state);
}

# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers)
# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers)
# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers)
# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers)
# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state),

#else // SPLIT_LED_STATE_ENABLE
Expand Down Expand Up @@ -360,8 +360,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave
# endif
}

# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers)
# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers)
# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers)
# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers)
# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods),

#else // SPLIT_MODS_ENABLE
Expand All @@ -385,8 +385,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t

static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); }

# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers)
# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers)
# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers)
# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers)
# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level),

#else // BACKLIGHT_ENABLE
Expand Down Expand Up @@ -422,8 +422,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
}
}

# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers)
# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers)
# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers)
# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers)
# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync),

#else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
Expand Down Expand Up @@ -452,8 +452,8 @@ static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state);
}

# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers)
# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers)
# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers)
# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers)
# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync),

#else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
Expand Down Expand Up @@ -482,8 +482,8 @@ static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state);
}

# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers)
# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers)
# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers)
# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers)
# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync),

#else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
Expand All @@ -507,8 +507,8 @@ static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave

static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); }

# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers)
# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers)
# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers)
# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers)
# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm),

#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)
Expand All @@ -519,6 +519,68 @@ static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_

#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)

////////////////////////////////////////////////////
// OLED

#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)

static bool oled_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
static uint32_t last_update = 0;
bool current_oled_state = is_oled_on();
return send_if_condition(PUT_OLED, &last_update, (current_oled_state = split_shmem->current_oled_state), &current_oled_state, sizeof(current_oled_state));
drashna marked this conversation as resolved.
Show resolved Hide resolved
}

static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
if (split_shmem->current_oled_state) {
oled_on();
} else {
oled_off();
}
}

# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled_handlers)
# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled_handlers)
# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state),

#else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)

# define TRANSACTIONS_OLED_MASTER()
# define TRANSACTIONS_OLED_SLAVE()
# define TRANSACTIONS_OLED_REGISTRATIONS

#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)

////////////////////////////////////////////////////
// ST7565

#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)

static bool st7565_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
static uint32_t last_update = 0;
bool current_st7565_state = st7565_is_on();
return send_if_condition(PUT_ST7565, &last_update, (current_st7565_state = split_shmem->current_st7565_state), &current_st7565_state, sizeof(current_st7565_state));
drashna marked this conversation as resolved.
Show resolved Hide resolved
}

static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
if (split_shmem->current_st7565_state) {
st7565_on();
} else {
st7565_off();
}
}

# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565_handlers)
# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565_handlers)
# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state),

#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)

# define TRANSACTIONS_ST7565_MASTER()
# define TRANSACTIONS_ST7565_SLAVE()
# define TRANSACTIONS_ST7565_REGISTRATIONS

#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)

////////////////////////////////////////////////////

uint8_t dummy;
Expand All @@ -543,6 +605,8 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
TRANSACTIONS_LED_MATRIX_REGISTRATIONS
TRANSACTIONS_RGB_MATRIX_REGISTRATIONS
TRANSACTIONS_WPM_REGISTRATIONS
TRANSACTIONS_OLED_REGISTRATIONS
TRANSACTIONS_ST7565_REGISTRATIONS
// clang-format on

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
Expand All @@ -567,6 +631,8 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
TRANSACTIONS_LED_MATRIX_MASTER();
TRANSACTIONS_RGB_MATRIX_MASTER();
TRANSACTIONS_WPM_MASTER();
TRANSACTIONS_OLED_MASTER();
TRANSACTIONS_ST7565_MASTER();
return okay;
}

Expand All @@ -583,6 +649,8 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[
TRANSACTIONS_LED_MATRIX_SLAVE();
TRANSACTIONS_RGB_MATRIX_SLAVE();
TRANSACTIONS_WPM_SLAVE();
TRANSACTIONS_OLED_SLAVE();
TRANSACTIONS_ST7565_SLAVE();
}

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
Expand Down
10 changes: 9 additions & 1 deletion quantum/split_common/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,19 @@ typedef struct _split_shared_memory_t {
uint8_t current_wpm;
#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)

#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)
uint8_t current_oled_state;
#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)

#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
uint8_t current_st7565_state;
#endif // ST7565_ENABLE(OLED_ENABLE) && defined(SPLIT_ST7565_ENABLE)

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
rpc_sync_info_t rpc_info;
uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE];
uint8_t rpc_s2m_buffer[RPC_S2M_BUFFER_SIZE];
#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
} split_shared_memory_t;

extern split_shared_memory_t *const split_shmem;
extern split_shared_memory_t *const split_shmem;