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

Add Split support for Haptic feedback #19203

Merged
merged 4 commits into from
Jan 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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/feature_split_keyboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ This enables transmitting the pointing device status to the master side of the s
!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration).
```c
#define SPLIT_HAPTIC_ENABLE
```
This enables triggering of haptic feedback on the slave side of the split keyboard. For DRV2605L this will send the mode, but for solenoids it is expected that the desired mode is already set up on the slave.
### 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
9 changes: 9 additions & 0 deletions quantum/haptic.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifdef SOLENOID_ENABLE
# include "solenoid.h"
#endif
#if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE)
extern uint8_t split_haptic_play;
#endif

haptic_config_t haptic_config;

Expand Down Expand Up @@ -319,9 +322,15 @@ void haptic_play(void) {
uint8_t play_eff = 0;
play_eff = haptic_config.mode;
DRV_pulse(play_eff);
# if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE)
split_haptic_play = haptic_config.mode;
# endif
#endif
#ifdef SOLENOID_ENABLE
solenoid_fire_handler();
# if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE)
split_haptic_play = 1;
# endif
#endif
}

Expand Down
4 changes: 4 additions & 0 deletions quantum/split_common/transaction_id_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ enum serial_transaction_id {
PUT_WATCHDOG,
#endif // defined(SPLIT_WATCHDOG_ENABLE)

#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
PUT_HAPTIC,
#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
PUT_RPC_INFO,
PUT_RPC_REQ_DATA,
Expand Down
45 changes: 45 additions & 0 deletions quantum/split_common/transactions.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,48 @@ static void watchdog_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s

#endif // defined(SPLIT_WATCHDOG_ENABLE)

#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)

uint8_t split_haptic_play = 0xFF;
extern haptic_config_t haptic_config;

static bool haptic_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
static uint32_t last_update = 0;
split_slave_haptic_sync_t haptic_sync;

memcpy(&haptic_sync.haptic_config, &haptic_config, sizeof(haptic_config_t));
haptic_sync.haptic_play = split_haptic_play;

bool okay = send_if_data_mismatch(PUT_HAPTIC, &last_update, &haptic_sync, &split_shmem->haptic_sync, sizeof(haptic_sync));

split_haptic_play = 0xFF;

return okay;
}

static void haptic_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
memcpy(&haptic_config, &split_shmem->haptic_sync.haptic_config, sizeof(haptic_config_t));

if (split_shmem->haptic_sync.haptic_play != 0xFF) {
haptic_set_mode(split_shmem->haptic_sync.haptic_play);
haptic_play();
}
}

// clang-format off
# define TRANSACTIONS_HAPTIC_MASTER() TRANSACTION_HANDLER_MASTER(haptic)
# define TRANSACTIONS_HAPTIC_SLAVE() TRANSACTION_HANDLER_SLAVE(haptic)
# define TRANSACTIONS_HAPTIC_REGISTRATIONS [PUT_HAPTIC] = trans_initiator2target_initializer(haptic_sync),
// clang-format on

#else // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)

# define TRANSACTIONS_HAPTIC_MASTER()
# define TRANSACTIONS_HAPTIC_SLAVE()
# define TRANSACTIONS_HAPTIC_REGISTRATIONS

#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)

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

split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
Expand Down Expand Up @@ -775,6 +817,7 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
TRANSACTIONS_ST7565_REGISTRATIONS
TRANSACTIONS_POINTING_REGISTRATIONS
TRANSACTIONS_WATCHDOG_REGISTRATIONS
TRANSACTIONS_HAPTIC_REGISTRATIONS
// clang-format on

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
Expand Down Expand Up @@ -802,6 +845,7 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
TRANSACTIONS_ST7565_MASTER();
TRANSACTIONS_POINTING_MASTER();
TRANSACTIONS_WATCHDOG_MASTER();
TRANSACTIONS_HAPTIC_MASTER();
return true;
}

Expand All @@ -822,6 +866,7 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[
TRANSACTIONS_ST7565_SLAVE();
TRANSACTIONS_POINTING_SLAVE();
TRANSACTIONS_WATCHDOG_SLAVE();
TRANSACTIONS_HAPTIC_SLAVE();
}

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
Expand Down
12 changes: 12 additions & 0 deletions quantum/split_common/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ typedef struct _split_slave_pointing_sync_t {
} split_slave_pointing_sync_t;
#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)

#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
# include "haptic.h"
typedef struct _split_slave_haptic_sync_t {
haptic_config_t haptic_config;
uint8_t haptic_play;
} split_slave_haptic_sync_t;
#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)

#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
typedef struct _rpc_sync_info_t {
uint8_t checksum;
Expand Down Expand Up @@ -192,6 +200,10 @@ typedef struct _split_shared_memory_t {
bool watchdog_pinged;
#endif // defined(SPLIT_WATCHDOG_ENABLE)

#if defined(HAPTIC_ENABLE)
split_slave_haptic_sync_t haptic_sync;
#endif // defined(HAPTIC_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];
Expand Down