summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/feature_split_keyboard.md6
-rw-r--r--quantum/haptic.c9
-rw-r--r--quantum/split_common/transaction_id_define.h4
-rw-r--r--quantum/split_common/transactions.c45
-rw-r--r--quantum/split_common/transport.h12
5 files changed, 76 insertions, 0 deletions
diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md
index 0b475cc63d..eaef975fb7 100644
--- a/docs/feature_split_keyboard.md
+++ b/docs/feature_split_keyboard.md
@@ -286,6 +286,12 @@ This enables transmitting the pointing device status to the master side of the s
286 286
287!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration). 287!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration).
288 288
289```c
290#define SPLIT_HAPTIC_ENABLE
291```
292
293This 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.
294
289### Custom data sync between sides :id=custom-data-sync 295### Custom data sync between sides :id=custom-data-sync
290 296
291QMK'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. 297QMK'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.
diff --git a/quantum/haptic.c b/quantum/haptic.c
index ad64fe2cc7..c151547fca 100644
--- a/quantum/haptic.c
+++ b/quantum/haptic.c
@@ -25,6 +25,9 @@
25#ifdef SOLENOID_ENABLE 25#ifdef SOLENOID_ENABLE
26# include "solenoid.h" 26# include "solenoid.h"
27#endif 27#endif
28#if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE)
29extern uint8_t split_haptic_play;
30#endif
28 31
29haptic_config_t haptic_config; 32haptic_config_t haptic_config;
30 33
@@ -319,9 +322,15 @@ void haptic_play(void) {
319 uint8_t play_eff = 0; 322 uint8_t play_eff = 0;
320 play_eff = haptic_config.mode; 323 play_eff = haptic_config.mode;
321 DRV_pulse(play_eff); 324 DRV_pulse(play_eff);
325# if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE)
326 split_haptic_play = haptic_config.mode;
327# endif
322#endif 328#endif
323#ifdef SOLENOID_ENABLE 329#ifdef SOLENOID_ENABLE
324 solenoid_fire_handler(); 330 solenoid_fire_handler();
331# if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE)
332 split_haptic_play = 1;
333# endif
325#endif 334#endif
326} 335}
327 336
diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h
index 8c19948107..18d3826b83 100644
--- a/quantum/split_common/transaction_id_define.h
+++ b/quantum/split_common/transaction_id_define.h
@@ -88,6 +88,10 @@ enum serial_transaction_id {
88 PUT_WATCHDOG, 88 PUT_WATCHDOG,
89#endif // defined(SPLIT_WATCHDOG_ENABLE) 89#endif // defined(SPLIT_WATCHDOG_ENABLE)
90 90
91#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
92 PUT_HAPTIC,
93#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
94
91#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) 95#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
92 PUT_RPC_INFO, 96 PUT_RPC_INFO,
93 PUT_RPC_REQ_DATA, 97 PUT_RPC_REQ_DATA,
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c
index 527b2f4caf..8e1961b586 100644
--- a/quantum/split_common/transactions.c
+++ b/quantum/split_common/transactions.c
@@ -748,6 +748,48 @@ static void watchdog_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
748 748
749#endif // defined(SPLIT_WATCHDOG_ENABLE) 749#endif // defined(SPLIT_WATCHDOG_ENABLE)
750 750
751#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
752
753uint8_t split_haptic_play = 0xFF;
754extern haptic_config_t haptic_config;
755
756static bool haptic_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
757 static uint32_t last_update = 0;
758 split_slave_haptic_sync_t haptic_sync;
759
760 memcpy(&haptic_sync.haptic_config, &haptic_config, sizeof(haptic_config_t));
761 haptic_sync.haptic_play = split_haptic_play;
762
763 bool okay = send_if_data_mismatch(PUT_HAPTIC, &last_update, &haptic_sync, &split_shmem->haptic_sync, sizeof(haptic_sync));
764
765 split_haptic_play = 0xFF;
766
767 return okay;
768}
769
770static void haptic_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
771 memcpy(&haptic_config, &split_shmem->haptic_sync.haptic_config, sizeof(haptic_config_t));
772
773 if (split_shmem->haptic_sync.haptic_play != 0xFF) {
774 haptic_set_mode(split_shmem->haptic_sync.haptic_play);
775 haptic_play();
776 }
777}
778
779// clang-format off
780# define TRANSACTIONS_HAPTIC_MASTER() TRANSACTION_HANDLER_MASTER(haptic)
781# define TRANSACTIONS_HAPTIC_SLAVE() TRANSACTION_HANDLER_SLAVE(haptic)
782# define TRANSACTIONS_HAPTIC_REGISTRATIONS [PUT_HAPTIC] = trans_initiator2target_initializer(haptic_sync),
783// clang-format on
784
785#else // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
786
787# define TRANSACTIONS_HAPTIC_MASTER()
788# define TRANSACTIONS_HAPTIC_SLAVE()
789# define TRANSACTIONS_HAPTIC_REGISTRATIONS
790
791#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
792
751//////////////////////////////////////////////////// 793////////////////////////////////////////////////////
752 794
753split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { 795split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
@@ -775,6 +817,7 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = {
775 TRANSACTIONS_ST7565_REGISTRATIONS 817 TRANSACTIONS_ST7565_REGISTRATIONS
776 TRANSACTIONS_POINTING_REGISTRATIONS 818 TRANSACTIONS_POINTING_REGISTRATIONS
777 TRANSACTIONS_WATCHDOG_REGISTRATIONS 819 TRANSACTIONS_WATCHDOG_REGISTRATIONS
820 TRANSACTIONS_HAPTIC_REGISTRATIONS
778// clang-format on 821// clang-format on
779 822
780#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) 823#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
@@ -802,6 +845,7 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix
802 TRANSACTIONS_ST7565_MASTER(); 845 TRANSACTIONS_ST7565_MASTER();
803 TRANSACTIONS_POINTING_MASTER(); 846 TRANSACTIONS_POINTING_MASTER();
804 TRANSACTIONS_WATCHDOG_MASTER(); 847 TRANSACTIONS_WATCHDOG_MASTER();
848 TRANSACTIONS_HAPTIC_MASTER();
805 return true; 849 return true;
806} 850}
807 851
@@ -822,6 +866,7 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[
822 TRANSACTIONS_ST7565_SLAVE(); 866 TRANSACTIONS_ST7565_SLAVE();
823 TRANSACTIONS_POINTING_SLAVE(); 867 TRANSACTIONS_POINTING_SLAVE();
824 TRANSACTIONS_WATCHDOG_SLAVE(); 868 TRANSACTIONS_WATCHDOG_SLAVE();
869 TRANSACTIONS_HAPTIC_SLAVE();
825} 870}
826 871
827#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) 872#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h
index 833633edc2..adee4470d2 100644
--- a/quantum/split_common/transport.h
+++ b/quantum/split_common/transport.h
@@ -114,6 +114,14 @@ typedef struct _split_slave_pointing_sync_t {
114} split_slave_pointing_sync_t; 114} split_slave_pointing_sync_t;
115#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) 115#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE)
116 116
117#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
118# include "haptic.h"
119typedef struct _split_slave_haptic_sync_t {
120 haptic_config_t haptic_config;
121 uint8_t haptic_play;
122} split_slave_haptic_sync_t;
123#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE)
124
117#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) 125#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
118typedef struct _rpc_sync_info_t { 126typedef struct _rpc_sync_info_t {
119 uint8_t checksum; 127 uint8_t checksum;
@@ -192,6 +200,10 @@ typedef struct _split_shared_memory_t {
192 bool watchdog_pinged; 200 bool watchdog_pinged;
193#endif // defined(SPLIT_WATCHDOG_ENABLE) 201#endif // defined(SPLIT_WATCHDOG_ENABLE)
194 202
203#if defined(HAPTIC_ENABLE)
204 split_slave_haptic_sync_t haptic_sync;
205#endif // defined(HAPTIC_ENABLE)
206
195#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) 207#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
196 rpc_sync_info_t rpc_info; 208 rpc_sync_info_t rpc_info;
197 uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE]; 209 uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE];