From be8907d634ac8967de1ae2ac8346b845f738c9e6 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 27 Sep 2022 18:37:13 +1000 Subject: [PATCH] Further refactoring of joystick feature (#18437) --- docs/feature_joystick.md | 81 ++++------ .../onekey/keymaps/joystick/keymap.c | 6 +- .../synthlabs/solo/keymaps/gamepad/keymap.c | 7 +- quantum/joystick.c | 98 ++++++++++- quantum/joystick.h | 28 +++- quantum/process_keycode/process_joystick.c | 152 ++---------------- quantum/process_keycode/process_joystick.h | 21 ++- tmk_core/protocol/chibios/usb_main.c | 54 +------ tmk_core/protocol/host.c | 56 +++++++ tmk_core/protocol/host_driver.h | 1 + tmk_core/protocol/lufa/lufa.c | 51 +----- tmk_core/protocol/report.h | 2 +- 12 files changed, 248 insertions(+), 309 deletions(-) diff --git a/docs/feature_joystick.md b/docs/feature_joystick.md index 2635298587..a82192bfe1 100644 --- a/docs/feature_joystick.md +++ b/docs/feature_joystick.md @@ -70,71 +70,44 @@ When the ADC reads 900 or higher, the returned axis value will be -127, whereas In this example, the first axis will be read from the `A4` pin while `B0` is set high and `A7` is set low, using `analogReadPin()`, whereas the second axis will not be read. -In order to give a value to the second axis, you can do so in any customizable entry point: as an action, in `process_record_user()` or in `matrix_scan_user()`, or even in `joystick_task()` which is called even when no key has been pressed. -You assign a value by writing to `joystick_status.axes[axis_index]` a signed 8-bit value (ranging from -127 to 127). Then it is necessary to assign the flag `JS_UPDATED` to `joystick_status.status` in order for an updated HID report to be sent. +#### Virtual Axes -The following example writes two axes based on keypad presses, with `KC_P5` as a precision modifier: +To give a value to virtual axes, call `joystick_set_axis(axis, value)`. + +The following example adjusts two virtual axes (X and Y) based on keypad presses, with `KC_P5` as a precision modifier: ```c -#ifdef ANALOG_JOYSTICK_ENABLE -static uint8_t precision_val = 70; -static uint8_t axesFlags = 0; -enum axes { - Precision = 1, - Axis1High = 2, - Axis1Low = 4, - Axis2High = 8, - Axis2Low = 16 +joystick_config_t joystick_axes[JOYSTICK_AXES_COUNT] = { + [0] = JOYSTICK_AXIS_VIRTUAL, // x + [1] = JOYSTICK_AXIS_VIRTUAL // y }; -#endif + +static bool precision = false; +static uint16_t precision_mod = 64; +static uint16_t axis_val = 127; bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { -#ifdef ANALOG_JOYSTICK_ENABLE - // virtual joystick -# if JOYSTICK_AXES_COUNT > 1 + int16_t precision_val = axis_val; + if (precision) { + precision_val -= precision_mod; + } + + switch (keycode) { case KC_P8: - if (record->event.pressed) { - axesFlags |= Axis2Low; - } else { - axesFlags &= ~Axis2Low; - } - joystick_status.status |= JS_UPDATED; - break; + joystick_set_axis(1, record->event.pressed ? -precision_val : 0); + return false; case KC_P2: - if (record->event.pressed) { - axesFlags |= Axis2High; - } else { - axesFlags &= ~Axis2High; - } - joystick_status.status |= JS_UPDATED; - break; -# endif + joystick_set_axis(1, record->event.pressed ? precision_val : 0); + return false; case KC_P4: - if (record->event.pressed) { - axesFlags |= Axis1Low; - } else { - axesFlags &= ~Axis1Low; - } - joystick_status.status |= JS_UPDATED; - break; + joystick_set_axis(0, record->event.pressed ? -precision_val : 0); + return false; case KC_P6: - if (record->event.pressed) { - axesFlags |= Axis1High; - } else { - axesFlags &= ~Axis1High; - } - joystick_status.status |= JS_UPDATED; - break; + joystick_set_axis(0, record->event.pressed ? precision_val : 0); + return false; case KC_P5: - if (record->event.pressed) { - axesFlags |= Precision; - } else { - axesFlags &= ~Precision; - } - joystick_status.status |= JS_UPDATED; - break; -#endif + precision = record->event.pressed; + return false; } return true; } diff --git a/keyboards/handwired/onekey/keymaps/joystick/keymap.c b/keyboards/handwired/onekey/keymaps/joystick/keymap.c index 7a2f138b28..c74707e931 100644 --- a/keyboards/handwired/onekey/keymaps/joystick/keymap.c +++ b/keyboards/handwired/onekey/keymaps/joystick/keymap.c @@ -10,11 +10,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { void matrix_scan_user() { int16_t val = (((uint32_t)timer_read() % 5000 - 2500) * 255) / 5000; - - if (val != joystick_status.axes[1]) { - joystick_status.axes[1] = val; - joystick_status.status |= JS_UPDATED; - } + joystick_set_axis(1, val); } // Joystick config diff --git a/keyboards/synthlabs/solo/keymaps/gamepad/keymap.c b/keyboards/synthlabs/solo/keymaps/gamepad/keymap.c index 3e55f346f1..8da2afc97a 100644 --- a/keyboards/synthlabs/solo/keymaps/gamepad/keymap.c +++ b/keyboards/synthlabs/solo/keymaps/gamepad/keymap.c @@ -3,8 +3,6 @@ #include QMK_KEYBOARD_H -#include "joystick.h" - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_all( JS_BUTTON0,JS_BUTTON1,JS_BUTTON2,JS_BUTTON3,JS_BUTTON4,JS_BUTTON5,JS_BUTTON6, @@ -24,11 +22,8 @@ joystick_config_t joystick_axes[JOYSTICK_AXES_COUNT] = { bool encoder_update_kb(uint8_t index, bool clockwise) { joystick_position += (clockwise ? 2 : -2) * (full_joystick_value / pulses_per_revolution); // +2 and -2 are used, since +1.0 and -1.0 axis output refers to positions at half of a full rotation + joystick_set_axis(0, joystick_position); - if (joystick_position != joystick_status.axes[0]) { - joystick_status.axes[0] = joystick_position; - joystick_status.status |= JS_UPDATED; - } return true; } diff --git a/quantum/joystick.c b/quantum/joystick.c index 86b2c64036..d285dcdb5e 100644 --- a/quantum/joystick.c +++ b/quantum/joystick.c @@ -1,5 +1,24 @@ +/* Copyright 2022 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include "joystick.h" +#include "analog.h" +#include "wait.h" + // clang-format off joystick_t joystick_status = { .buttons = {0}, @@ -15,12 +34,13 @@ joystick_t joystick_status = { // array defining the reading of analog values for each axis __attribute__((weak)) joystick_config_t joystick_axes[JOYSTICK_AXES_COUNT] = {}; -// to be implemented in the hid protocol library -void send_joystick_packet(joystick_t *joystick); +__attribute__((weak)) void joystick_task(void) { + joystick_read_axes(); +} void joystick_flush(void) { if ((joystick_status.status & JS_UPDATED) > 0) { - send_joystick_packet(&joystick_status); + host_joystick_send(&joystick_status); joystick_status.status &= ~JS_UPDATED; } } @@ -36,3 +56,75 @@ void unregister_joystick_button(uint8_t button) { joystick_status.status |= JS_UPDATED; joystick_flush(); } + +int16_t joystick_read_axis(uint8_t axis) { + // disable pull-up resistor + writePinLow(joystick_axes[axis].input_pin); + + // if pin was a pull-up input, we need to uncharge it by turning it low + // before making it a low input + setPinOutput(joystick_axes[axis].input_pin); + + wait_us(10); + + if (joystick_axes[axis].output_pin != JS_VIRTUAL_AXIS) { + setPinOutput(joystick_axes[axis].output_pin); + writePinHigh(joystick_axes[axis].output_pin); + } + + if (joystick_axes[axis].ground_pin != JS_VIRTUAL_AXIS) { + setPinOutput(joystick_axes[axis].ground_pin); + writePinLow(joystick_axes[axis].ground_pin); + } + + wait_us(10); + + setPinInput(joystick_axes[axis].input_pin); + + wait_us(10); + +#if defined(ANALOG_JOYSTICK_ENABLE) && (defined(__AVR__) || defined(PROTOCOL_CHIBIOS)) + int16_t axis_val = analogReadPin(joystick_axes[axis].input_pin); +#else + // default to resting position + int16_t axis_val = joystick_axes[axis].mid_digit; +#endif + + // test the converted value against the lower range + int32_t ref = joystick_axes[axis].mid_digit; + int32_t range = joystick_axes[axis].min_digit; + int32_t ranged_val = ((axis_val - ref) * -JOYSTICK_RESOLUTION) / (range - ref); + + if (ranged_val > 0) { + // the value is in the higher range + range = joystick_axes[axis].max_digit; + ranged_val = ((axis_val - ref) * JOYSTICK_RESOLUTION) / (range - ref); + } + + // clamp the result in the valid range + ranged_val = ranged_val < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val; + ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val; + + return ranged_val; +} + +void joystick_read_axes() { +#if JOYSTICK_AXES_COUNT > 0 + for (int i = 0; i < JOYSTICK_AXES_COUNT; ++i) { + if (joystick_axes[i].input_pin == JS_VIRTUAL_AXIS) { + continue; + } + + joystick_set_axis(i, joystick_read_axis(i)); + } + + joystick_flush(); +#endif +} + +void joystick_set_axis(uint8_t axis, int16_t value) { + if (value != joystick_status.axes[axis]) { + joystick_status.axes[axis] = value; + joystick_status.status |= JS_UPDATED; + } +} diff --git a/quantum/joystick.h b/quantum/joystick.h index 5d81b14ef2..ee966fdb1a 100644 --- a/quantum/joystick.h +++ b/quantum/joystick.h @@ -1,3 +1,19 @@ +/* Copyright 2022 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #pragma once #include @@ -54,7 +70,10 @@ typedef struct { extern joystick_config_t joystick_axes[JOYSTICK_AXES_COUNT]; -enum joystick_status { JS_INITIALIZED = 1, JS_UPDATED = 2 }; +enum joystick_status { + JS_INITIALIZED = 1, + JS_UPDATED, +}; typedef struct { uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; @@ -65,7 +84,14 @@ typedef struct { extern joystick_t joystick_status; +void joystick_task(void); void joystick_flush(void); void register_joystick_button(uint8_t button); void unregister_joystick_button(uint8_t button); + +int16_t joystick_read_axis(uint8_t axis); +void joystick_read_axes(void); +void joystick_set_axis(uint8_t axis, int16_t value); + +void host_joystick_send(joystick_t *joystick); diff --git a/quantum/process_keycode/process_joystick.c b/quantum/process_keycode/process_joystick.c index e867606074..af69d3aa05 100644 --- a/quantum/process_keycode/process_joystick.c +++ b/quantum/process_keycode/process_joystick.c @@ -1,10 +1,21 @@ -#include "joystick.h" +/* Copyright 2022 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include "process_joystick.h" - -#include "analog.h" - -#include -#include +#include "joystick.h" bool process_joystick(uint16_t keycode, keyrecord_t *record) { switch (keycode) { @@ -18,132 +29,3 @@ bool process_joystick(uint16_t keycode, keyrecord_t *record) { } return true; } - -__attribute__((weak)) void joystick_task(void) { - if (process_joystick_analogread()) { - joystick_flush(); - } -} - -uint16_t savePinState(pin_t pin) { -#ifdef __AVR__ - uint8_t pinNumber = pin & 0xF; - return ((PORTx_ADDRESS(pin) >> pinNumber) & 0x1) << 1 | ((DDRx_ADDRESS(pin) >> pinNumber) & 0x1); -#elif defined(PROTOCOL_CHIBIOS) - /* - The pin configuration is backed up in the following format : - bit 15 9 8 7 6 5 4 3 2 1 0 - |unused|ODR|IDR|PUPDR|OSPEEDR|OTYPER|MODER| - */ - return ((PAL_PORT(pin)->MODER >> (2 * PAL_PAD(pin))) & 0x3) | (((PAL_PORT(pin)->OTYPER >> (1 * PAL_PAD(pin))) & 0x1) << 2) | (((PAL_PORT(pin)->OSPEEDR >> (2 * PAL_PAD(pin))) & 0x3) << 3) | (((PAL_PORT(pin)->PUPDR >> (2 * PAL_PAD(pin))) & 0x3) << 5) | (((PAL_PORT(pin)->IDR >> (1 * PAL_PAD(pin))) & 0x1) << 7) | (((PAL_PORT(pin)->ODR >> (1 * PAL_PAD(pin))) & 0x1) << 8); -#else - return 0; -#endif -} - -void restorePinState(pin_t pin, uint16_t restoreState) { -#if defined(PROTOCOL_LUFA) - uint8_t pinNumber = pin & 0xF; - PORTx_ADDRESS(pin) = (PORTx_ADDRESS(pin) & ~_BV(pinNumber)) | (((restoreState >> 1) & 0x1) << pinNumber); - DDRx_ADDRESS(pin) = (DDRx_ADDRESS(pin) & ~_BV(pinNumber)) | ((restoreState & 0x1) << pinNumber); -#elif defined(PROTOCOL_CHIBIOS) - PAL_PORT(pin)->MODER = (PAL_PORT(pin)->MODER & ~(0x3 << (2 * PAL_PAD(pin)))) | (restoreState & 0x3) << (2 * PAL_PAD(pin)); - PAL_PORT(pin)->OTYPER = (PAL_PORT(pin)->OTYPER & ~(0x1 << (1 * PAL_PAD(pin)))) | ((restoreState >> 2) & 0x1) << (1 * PAL_PAD(pin)); - PAL_PORT(pin)->OSPEEDR = (PAL_PORT(pin)->OSPEEDR & ~(0x3 << (2 * PAL_PAD(pin)))) | ((restoreState >> 3) & 0x3) << (2 * PAL_PAD(pin)); - PAL_PORT(pin)->PUPDR = (PAL_PORT(pin)->PUPDR & ~(0x3 << (2 * PAL_PAD(pin)))) | ((restoreState >> 5) & 0x3) << (2 * PAL_PAD(pin)); - PAL_PORT(pin)->IDR = (PAL_PORT(pin)->IDR & ~(0x1 << (1 * PAL_PAD(pin)))) | ((restoreState >> 7) & 0x1) << (1 * PAL_PAD(pin)); - PAL_PORT(pin)->ODR = (PAL_PORT(pin)->ODR & ~(0x1 << (1 * PAL_PAD(pin)))) | ((restoreState >> 8) & 0x1) << (1 * PAL_PAD(pin)); -#else - return; -#endif -} - -__attribute__((weak)) bool process_joystick_analogread() { - return process_joystick_analogread_quantum(); -} - -bool process_joystick_analogread_quantum() { -#if JOYSTICK_AXES_COUNT > 0 - for (int axis_index = 0; axis_index < JOYSTICK_AXES_COUNT; ++axis_index) { - if (joystick_axes[axis_index].input_pin == JS_VIRTUAL_AXIS) { - continue; - } - - // save previous input pin status as well - uint16_t inputSavedState = savePinState(joystick_axes[axis_index].input_pin); - - // disable pull-up resistor - writePinLow(joystick_axes[axis_index].input_pin); - - // if pin was a pull-up input, we need to uncharge it by turning it low - // before making it a low input - setPinOutput(joystick_axes[axis_index].input_pin); - - wait_us(10); - - // save and apply output pin status - uint16_t outputSavedState = 0; - if (joystick_axes[axis_index].output_pin != JS_VIRTUAL_AXIS) { - // save previous output pin status - outputSavedState = savePinState(joystick_axes[axis_index].output_pin); - - setPinOutput(joystick_axes[axis_index].output_pin); - writePinHigh(joystick_axes[axis_index].output_pin); - } - - uint16_t groundSavedState = 0; - if (joystick_axes[axis_index].ground_pin != JS_VIRTUAL_AXIS) { - // save previous output pin status - groundSavedState = savePinState(joystick_axes[axis_index].ground_pin); - - setPinOutput(joystick_axes[axis_index].ground_pin); - writePinLow(joystick_axes[axis_index].ground_pin); - } - - wait_us(10); - - setPinInput(joystick_axes[axis_index].input_pin); - - wait_us(10); - -# if defined(ANALOG_JOYSTICK_ENABLE) && (defined(__AVR__) || defined(PROTOCOL_CHIBIOS)) - int16_t axis_val = analogReadPin(joystick_axes[axis_index].input_pin); -# else - // default to resting position - int16_t axis_val = joystick_axes[axis_index].mid_digit; -# endif - - // test the converted value against the lower range - int32_t ref = joystick_axes[axis_index].mid_digit; - int32_t range = joystick_axes[axis_index].min_digit; - int32_t ranged_val = ((axis_val - ref) * -JOYSTICK_RESOLUTION) / (range - ref); - - if (ranged_val > 0) { - // the value is in the higher range - range = joystick_axes[axis_index].max_digit; - ranged_val = ((axis_val - ref) * JOYSTICK_RESOLUTION) / (range - ref); - } - - // clamp the result in the valid range - ranged_val = ranged_val < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val; - ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val; - - if (ranged_val != joystick_status.axes[axis_index]) { - joystick_status.axes[axis_index] = ranged_val; - joystick_status.status |= JS_UPDATED; - } - - // restore output, ground and input status - if (joystick_axes[axis_index].output_pin != JS_VIRTUAL_AXIS) { - restorePinState(joystick_axes[axis_index].output_pin, outputSavedState); - } - if (joystick_axes[axis_index].ground_pin != JS_VIRTUAL_AXIS) { - restorePinState(joystick_axes[axis_index].ground_pin, groundSavedState); - } - - restorePinState(joystick_axes[axis_index].input_pin, inputSavedState); - } - -#endif - return true; -} diff --git a/quantum/process_keycode/process_joystick.h b/quantum/process_keycode/process_joystick.h index 7a8b82913a..1fb8757708 100644 --- a/quantum/process_keycode/process_joystick.h +++ b/quantum/process_keycode/process_joystick.h @@ -1,11 +1,22 @@ +/* Copyright 2022 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #pragma once #include #include "quantum.h" bool process_joystick(uint16_t keycode, keyrecord_t *record); - -void joystick_task(void); - -bool process_joystick_analogread(void); -bool process_joystick_analogread_quantum(void); diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index 222a867e3c..7c44b87bc4 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -50,10 +50,6 @@ extern keymap_config_t keymap_config; #endif -#ifdef JOYSTICK_ENABLE -# include "joystick.h" -#endif - /* --------------------------------------------------------- * Global interface variables and declarations * --------------------------------------------------------- @@ -1151,59 +1147,15 @@ void virtser_task(void) { #endif +void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE - -void send_joystick_packet(joystick_t *joystick) { - static joystick_report_t rep; - rep = (joystick_report_t) { -# if JOYSTICK_AXES_COUNT > 0 - .axes = - { joystick->axes[0], - -# if JOYSTICK_AXES_COUNT >= 2 - joystick->axes[1], -# endif -# if JOYSTICK_AXES_COUNT >= 3 - joystick->axes[2], -# endif -# if JOYSTICK_AXES_COUNT >= 4 - joystick->axes[3], -# endif -# if JOYSTICK_AXES_COUNT >= 5 - joystick->axes[4], -# endif -# if JOYSTICK_AXES_COUNT >= 6 - joystick->axes[5], -# endif - }, -# endif // JOYSTICK_AXES_COUNT>0 - -# if JOYSTICK_BUTTON_COUNT > 0 - .buttons = { - joystick->buttons[0], - -# if JOYSTICK_BUTTON_COUNT > 8 - joystick->buttons[1], -# endif -# if JOYSTICK_BUTTON_COUNT > 16 - joystick->buttons[2], -# endif -# if JOYSTICK_BUTTON_COUNT > 24 - joystick->buttons[3], -# endif - } -# endif // JOYSTICK_BUTTON_COUNT>0 - }; - - // chnWrite(&drivers.joystick_driver.driver, (uint8_t *)&rep, sizeof(rep)); osalSysLock(); if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { osalSysUnlock(); return; } - usbStartTransmitI(&USB_DRIVER, JOYSTICK_IN_EPNUM, (uint8_t *)&rep, sizeof(joystick_report_t)); + usbStartTransmitI(&USB_DRIVER, JOYSTICK_IN_EPNUM, (uint8_t *)report, sizeof(report_joystick_t)); osalSysUnlock(); -} - #endif +} diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c index 53854b94fb..99298ad6d6 100644 --- a/tmk_core/protocol/host.c +++ b/tmk_core/protocol/host.c @@ -24,6 +24,10 @@ along with this program. If not, see . #include "debug.h" #include "digitizer.h" +#ifdef JOYSTICK_ENABLE +# include "joystick.h" +#endif + #ifdef BLUETOOTH_ENABLE # include "outputselect.h" # ifdef BLUETOOTH_BLUEFRUIT_LE @@ -161,6 +165,58 @@ void host_consumer_send(uint16_t report) { (*driver->send_extra)(REPORT_ID_CONSUMER, report); } +#ifdef JOYSTICK_ENABLE +void host_joystick_send(joystick_t *joystick) { + if (!driver) return; + + report_joystick_t report = { +# if JOYSTICK_AXES_COUNT > 0 + .axes = + { + joystick->axes[0], + +# if JOYSTICK_AXES_COUNT >= 2 + joystick->axes[1], +# endif +# if JOYSTICK_AXES_COUNT >= 3 + joystick->axes[2], +# endif +# if JOYSTICK_AXES_COUNT >= 4 + joystick->axes[3], +# endif +# if JOYSTICK_AXES_COUNT >= 5 + joystick->axes[4], +# endif +# if JOYSTICK_AXES_COUNT >= 6 + joystick->axes[5], +# endif + }, +# endif + +# if JOYSTICK_BUTTON_COUNT > 0 + .buttons = + { + joystick->buttons[0], + +# if JOYSTICK_BUTTON_COUNT > 8 + joystick->buttons[1], +# endif +# if JOYSTICK_BUTTON_COUNT > 16 + joystick->buttons[2], +# endif +# if JOYSTICK_BUTTON_COUNT > 24 + joystick->buttons[3], +# endif + }, +# endif + }; + + send_joystick(&report); +} +#endif + +__attribute__((weak)) void send_joystick(report_joystick_t *report) {} + void host_digitizer_send(digitizer_t *digitizer) { if (!driver) return; diff --git a/tmk_core/protocol/host_driver.h b/tmk_core/protocol/host_driver.h index 680d9727d3..ae6e40ddc3 100644 --- a/tmk_core/protocol/host_driver.h +++ b/tmk_core/protocol/host_driver.h @@ -31,4 +31,5 @@ typedef struct { void (*send_programmable_button)(uint32_t); } host_driver_t; +void send_joystick(report_joystick_t *report); void send_digitizer(report_digitizer_t *report); diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 2a3f5fd883..6012d96fd5 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -77,10 +77,6 @@ extern keymap_config_t keymap_config; # include "raw_hid.h" #endif -#ifdef JOYSTICK_ENABLE -# include "joystick.h" -#endif - uint8_t keyboard_idle = 0; /* 0: Boot Protocol, 1: Report Protocol(default) */ uint8_t keyboard_protocol = 1; @@ -261,51 +257,10 @@ static void Console_Task(void) { /******************************************************************************* * Joystick ******************************************************************************/ +void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE -void send_joystick_packet(joystick_t *joystick) { uint8_t timeout = 255; - static joystick_report_t r; - r = (joystick_report_t) { -# if JOYSTICK_AXES_COUNT > 0 - .axes = - { joystick->axes[0], - -# if JOYSTICK_AXES_COUNT >= 2 - joystick->axes[1], -# endif -# if JOYSTICK_AXES_COUNT >= 3 - joystick->axes[2], -# endif -# if JOYSTICK_AXES_COUNT >= 4 - joystick->axes[3], -# endif -# if JOYSTICK_AXES_COUNT >= 5 - joystick->axes[4], -# endif -# if JOYSTICK_AXES_COUNT >= 6 - joystick->axes[5], -# endif - }, -# endif // JOYSTICK_AXES_COUNT>0 - -# if JOYSTICK_BUTTON_COUNT > 0 - .buttons = { - joystick->buttons[0], - -# if JOYSTICK_BUTTON_COUNT > 8 - joystick->buttons[1], -# endif -# if JOYSTICK_BUTTON_COUNT > 16 - joystick->buttons[2], -# endif -# if JOYSTICK_BUTTON_COUNT > 24 - joystick->buttons[3], -# endif - } -# endif // JOYSTICK_BUTTON_COUNT>0 - }; - /* Select the Joystick Report Endpoint */ Endpoint_SelectEndpoint(JOYSTICK_IN_EPNUM); @@ -315,12 +270,12 @@ void send_joystick_packet(joystick_t *joystick) { if (!Endpoint_IsReadWriteAllowed()) return; /* Write Joystick Report Data */ - Endpoint_Write_Stream_LE(&r, sizeof(joystick_report_t), NULL); + Endpoint_Write_Stream_LE(report, sizeof(report_joystick_t), NULL); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); -} #endif +} /******************************************************************************* * USB Events diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h index b4dbf92a8f..8bc4a57c0c 100644 --- a/tmk_core/protocol/report.h +++ b/tmk_core/protocol/report.h @@ -245,7 +245,7 @@ typedef struct { #if JOYSTICK_BUTTON_COUNT > 0 uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; #endif -} __attribute__((packed)) joystick_report_t; +} __attribute__((packed)) report_joystick_t; /* keycode to system usage */ static inline uint16_t KEYCODE2SYSTEM(uint8_t key) {