diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/ChangeLog/20220226/PR15304.md | 13 | ||||
-rw-r--r-- | docs/feature_haptic_feedback.md | 4 | ||||
-rw-r--r-- | docs/feature_key_lock.md | 3 | ||||
-rw-r--r-- | docs/feature_pointing_device.md | 122 | ||||
-rw-r--r-- | docs/feature_split_keyboard.md | 8 | ||||
-rw-r--r-- | docs/feature_wpm.md | 2 | ||||
-rw-r--r-- | docs/internals_gpio_control.md | 24 | ||||
-rw-r--r-- | docs/keycodes.md | 1 | ||||
-rw-r--r-- | docs/keycodes_magic.md | 1 |
9 files changed, 149 insertions, 29 deletions
diff --git a/docs/ChangeLog/20220226/PR15304.md b/docs/ChangeLog/20220226/PR15304.md new file mode 100644 index 0000000000..3cdb40db10 --- /dev/null +++ b/docs/ChangeLog/20220226/PR15304.md @@ -0,0 +1,13 @@ +### Split Common core now supports Pointing Devices ([#15304](https://github.com/qmk/qmk_firmware/pull/15304)) + +Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side. + +This feature can be enabled with `#define SPLIT_POINTING_ENABLE` and one of the following options: + +| Setting | Description | +|---------------------------|------------------------------------| +|`POINTING_DEVICE_LEFT` | Pointing device on the left side | +|`POINTING_DEVICE_RIGHT` | Pointing device on the right side | +|`POINTING_DEVICE_COMBINED` | Pointing device on both sides | + +See the [Pointing Device](../feature_pointing_device.md) documentation for further configuration options. diff --git a/docs/feature_haptic_feedback.md b/docs/feature_haptic_feedback.md index c8c74cb8f0..bbdf7e122c 100644 --- a/docs/feature_haptic_feedback.md +++ b/docs/feature_haptic_feedback.md @@ -167,7 +167,7 @@ List of waveform sequences from the datasheet: ``` #define DRV_GREETING *sequence name or number* ``` -If haptic feedback is enabled, the keyboard will vibrate to a specific sqeuence during startup. That can be selected using the following define: +If haptic feedback is enabled, the keyboard will vibrate to a specific sequence during startup. That can be selected using the following define: ``` #define DRV_MODE_DEFAULT *sequence name or number* @@ -207,4 +207,4 @@ With the entry of `#define NO_HAPTIC_LOCKKEYS` in config.h, none of the followin With the entry of `#define NO_HAPTIC_NAV` in config.h, none of the following keys will trigger a feedback: Print Screen, Pause, Insert, Delete, Page Down, Page Up, Left Arrow, Up Arrow, Right Arrow, Down Arrow, End, Home. ### NO_HAPTIC_NUMERIC -With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback.
\ No newline at end of file +With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback. diff --git a/docs/feature_key_lock.md b/docs/feature_key_lock.md index 8e6e29f0e6..7681394229 100644 --- a/docs/feature_key_lock.md +++ b/docs/feature_key_lock.md @@ -19,4 +19,5 @@ First, enable Key Lock by setting `KEY_LOCK_ENABLE = yes` in your `rules.mk`. Th Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(KC_LSFT)`). This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held. -Switching layers will not cancel the Key Lock. +Switching layers will not cancel the Key Lock. The Key Lock can be cancelled by calling the `cancel_key_lock()` function. + diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index bd7fb36589..f8de92f3b4 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -30,7 +30,7 @@ The ADNS 5050 sensor uses a serial type protocol for communication, and requires The CPI range is 125-1375, in increments of 125. Defaults to 500 CPI. -### ADSN 9800 Sensor +### ADNS 9800 Sensor To use the ADNS 9800 sensor, add this to your `rules.mk` @@ -69,7 +69,7 @@ The Analog Joystick is an analog (ADC) driven sensor. There are a variety of jo |`ANALOG_JOYSTICK_AXIS_MAX` | (Optional) Sets the upper range to be considered movement. | `1023` | |`ANALOG_JOYSTICK_SPEED_REGULATOR` | (Optional) The divisor used to slow down movement. (lower makes it faster) | `20` | |`ANALOG_JOYSTICK_READ_INTERVAL` | (Optional) The interval in milliseconds between reads. | `10` | -|`ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maxiumum value used for motion. | `2` | +|`ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maximum value used for motion. | `2` | |`ANALOG_JOYSTICK_CLICK_PIN` | (Optional) The pin wired up to the press switch of the analog stick. | _not defined_ | @@ -127,11 +127,10 @@ The Pimoroni Trackball module is a I2C based breakout board with an RGB enable t | Setting | Description | Default | |-------------------------------------|------------------------------------------------------------------------------------|---------| |`PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` | -|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `100` | -|`PIMORONI_TRACKBALL_INTERVAL_MS` | (Optional) The update/read interval for the sensor in milliseconds. | `8` | +|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` | |`PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` | |`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` | -|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` | +|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` | ### PMW 3360 Sensor @@ -171,14 +170,35 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {} ## Common Configuration -| Setting | Description | Default | -|-------------------------------|-----------------------------------------------------------------------|---------------| -|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | -|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | -|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | -|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ | -|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ | -|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ | +| Setting | Description | Default | +|----------------------------------|-----------------------------------------------------------------------|-------------------| +|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | +|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | +|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | +|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ | +|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ | +|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ | +|`POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ | + +!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and would recommend `POINTING_DEVICE_TASK_THROTTLE_MS` be set to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness. + + +## Split Keyboard Configuration + +The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device. + +| Setting | Description | Default | +|----------------------------------------|-----------------------------------------------------------------------|---------------| +|`POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ | +|`POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ | +|`POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ | +|`POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | +|`POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | +|`POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | +|`POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ | +|`POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ | + +!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware. ## Callbacks and Functions @@ -188,7 +208,7 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {} | `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. | | `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. | | `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. | -| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user coe can intercept and modify the data. Returns a mouse report. | +| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user code can intercept and modify the data. Returns a mouse report. | | `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. | | `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. | | `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. | @@ -196,6 +216,21 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {} | `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. | | `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. | | `has_mouse_report_changed(old, new)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. | +| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. | + + +## Split Keyboard Callbacks and Functions + +The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices) + +| Function | Description | +|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------| +| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `mouse_report_t` data structured passed to the function. | +| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right` | +| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `mouse_report_t` data structure) | +| `pointing_device_task_combined_kb(left_report, right_report)` | Callback, so keyboard code can intercept and modify the data. Returns a combined mouse report. | +| `pointing_device_task_combined_user(left_report, right_report)` | Callback, so user code can intercept and modify. Returns a combined mouse report using `pointing_device_combine_reports` | +| `pointing_device_adjust_by_defines_right(mouse_report)` | Applies right side rotations and invert configurations to a raw mouse report. | # Manipulating Mouse Reports @@ -242,3 +277,62 @@ case MS_SPECIAL: ``` Recall that the mouse report is set to zero (except the buttons) whenever it is sent, so the scrolling would only occur once in each case. + +## Split Examples + +The following examples make use the `SPLIT_POINTING_ENABLE` functionality and show how to manipulate the mouse report for a scrolling mode. + +### Single Pointing Device + +The following example will work with either `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` and enables scrolling mode while on a particular layer. + +```c + +static bool scrolling_mode = false; + +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { + case _RAISE: // If we're on the _RAISE layer enable scrolling mode + scrolling_mode = true; + pointing_device_set_cpi(2000); + break; + default: + if (scrolling_mode) { // check if we were scrolling before and set disable if so + scrolling_mode = false; + pointing_device_set_cpi(8000); + } + break; + } + return state; +} + +report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { + if (scrolling_mode) { + mouse_report.h = mouse_report.x; + mouse_report.v = mouse_report.y; + mouse_report.x = 0; + mouse_report.y = 0; + } + return mouse_report; +} + +``` + +### Combined Pointing Devices + +The following example requires `POINTING_DEVICE_COMBINED` and sets the left side pointing device to scroll only. + +```c +void keyboard_post_init_user(void) { + pointing_device_set_cpi_on_side(true, 1000); //Set cpi on left side to a low value for slower scrolling. + pointing_device_set_cpi_on_side(false, 8000); //Set cpi on right side to a reasonable value for mousing. +} + +report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) { + left_report.h = left_report.x; + left_report.v = left_report.y; + left_report.x = 0; + left_report.y = 0; + return pointing_device_combine_reports(left_report, right_report); +} +``` diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md index c8ba18beeb..b51593308e 100644 --- a/docs/feature_split_keyboard.md +++ b/docs/feature_split_keyboard.md @@ -266,6 +266,14 @@ This enables transmitting the current OLED on/off status to the slave side of th 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. +```c +#define SPLIT_POINTING_ENABLE +``` + +This enables transmitting the pointing device status to the master side of the split keyboard. The purpose of this feature is to enable use pointing devices on the slave side. + +!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration). + ### 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. diff --git a/docs/feature_wpm.md b/docs/feature_wpm.md index 87145c97e3..9f98ef8336 100644 --- a/docs/feature_wpm.md +++ b/docs/feature_wpm.md @@ -16,7 +16,7 @@ For split keyboards using soft serial, the computed WPM score will be available | `WPM_ALLOW_COUNT_REGRESSION` | _Not defined_ | If defined allows the WPM to be decreased when hitting Delete or Backspace | | `WPM_UNFILTERED` | _Not defined_ | If undefined (the default), WPM values will be smoothed to avoid sudden changes in value | | `WPM_SAMPLE_SECONDS` | `5` | This defines how many seconds of typing to average, when calculating WPM | -| `WPM_SAMPLE_PERIODS` | `50` | This defines how many sampling periods to use when calculating WPM | +| `WPM_SAMPLE_PERIODS` | `25` | This defines how many sampling periods to use when calculating WPM | | `WPM_LAUNCH_CONTROL` | _Not defined_ | If defined, WPM values will be calculated using partial buffers when typing begins | 'WPM_UNFILTERED' is potentially useful if you're filtering data in some other way (and also because it reduces the code required for the WPM feature), or if reducing measurement latency to a minimum is important for you. diff --git a/docs/internals_gpio_control.md b/docs/internals_gpio_control.md index ccd3f8c74d..e1f1515b71 100644 --- a/docs/internals_gpio_control.md +++ b/docs/internals_gpio_control.md @@ -6,17 +6,19 @@ QMK has a GPIO control abstraction layer which is microcontroller agnostic. This The following functions provide basic control of GPIOs and are found in `platforms/<platform>/gpio.h`. -|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples | -|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------| -| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | -| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | -| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | -| `setPinOutput(pin)` | Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | -| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | -| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | -| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | -| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | +| Function | Description | Old AVR Examples | Old ChibiOS/ARM Examples | +|------------------------------|-----------------------------------------------------|-------------------------------------------------|--------------------------------------------------| +| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | +| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | +| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | +| `setPinOutput(pin)` | Set pin as output (alias of `setPinOutputPushPull`) | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | +| `setPinOutputPushPull(pin)` | Set pin as output, push/pull mode | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | +| `setPinOutputOpenDrain(pin)` | Set pin as output, open-drain mode | N/A (Not implemented on AVR) | `palSetLineMode(pin, PAL_MODE_OUTPUT_OPENDRAIN)` | +| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | +| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | +| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | +| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | +| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | ## Advanced Settings :id=advanced-settings diff --git a/docs/keycodes.md b/docs/keycodes.md index ba06e1b8b6..2ea4fc74e2 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -326,6 +326,7 @@ See also: [Magic Keycodes](keycodes_magic.md) |----------------------------------|---------|--------------------------------------------------------------------------| |`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control | |`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control | +|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap | |`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control | |`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control | |`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI | diff --git a/docs/keycodes_magic.md b/docs/keycodes_magic.md index 7e1b1a4f62..01eb69168e 100644 --- a/docs/keycodes_magic.md +++ b/docs/keycodes_magic.md @@ -6,6 +6,7 @@ |----------------------------------|---------|--------------------------------------------------------------------------| |`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control | |`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control | +|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap | |`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control | |`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control | |`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI | |