diff --git a/keyboards/barobord/config.h b/keyboards/barobord/config.h index 20cef64e28..70d75caab7 100644 --- a/keyboards/barobord/config.h +++ b/keyboards/barobord/config.h @@ -91,3 +91,5 @@ along with this program. If not, see . #define LOCKING_SUPPORT_ENABLE /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE + +#define TRACKBALL_ORIENTATION 2 diff --git a/keyboards/barobord/keymaps/sadekbaroudi/keymap.c b/keyboards/barobord/keymaps/sadekbaroudi/keymap.c index 7f539891a6..4ff4d8fe45 100644 --- a/keyboards/barobord/keymaps/sadekbaroudi/keymap.c +++ b/keyboards/barobord/keymaps/sadekbaroudi/keymap.c @@ -47,7 +47,7 @@ K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \ LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \ K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE, K2A), \ - _______, _______, KC_LEAD, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT, _______, _______, \ + _______, _______, KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT, _______, _______, \ KC_MUTE, LCTL(KC_BSPC) \ ) diff --git a/keyboards/barobord/rules.mk b/keyboards/barobord/rules.mk index 0da69118ff..b8e65b8709 100644 --- a/keyboards/barobord/rules.mk +++ b/keyboards/barobord/rules.mk @@ -15,7 +15,6 @@ BOOTLOADER = atmel-dfu # change yes to no to disable # BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration -MOUSEKEY_ENABLE = no # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = no # Console for debug COMMAND_ENABLE = no # Commands for debug and configuration @@ -31,12 +30,14 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches ENCODER_ENABLE = yes -OLED_DRIVER_ENABLE = yes -THUMBSTICK_ENABLE = no -ifeq ($(strip $(THUMBSTICK_ENABLE)), yes) - POINTING_DEVICE_ENABLE = yes - OPT_DEFS += -DTHUMBSTICK_ENABLE - SRC += analog.c - SRC += thumbstick.c -endif \ No newline at end of file +# If you don't have pimoroni trackball +OLED_DRIVER_ENABLE = yes # this can be yes or no depending on if you have an OLED +MOUSEKEY_ENABLE = yes # Mouse keys + +# If you have pimoroni trackball +#OLED_DRIVER_ENABLE = yes # this must be yes since it uses the I2C for pimoroni +#PIMORONI_TRACKBALL_ENABLE = yes +# unfortunately, these two take up a lot of space, so you may need to disable macros :'( +#EXTRAFLAGS += -flto +#MOUSEKEY_ENABLE = no \ No newline at end of file diff --git a/keyboards/barobord/thumbstick.c b/keyboards/barobord/thumbstick.c deleted file mode 100644 index d3707dbc1b..0000000000 --- a/keyboards/barobord/thumbstick.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "thumbstick.h" - -void thumbstick_init(void) { - thumbstickTimer = 0; - thumbstickScrollTimer = 0; - thumbstick_state.config.mode = THUMBSTICK_MODE_MOUSE; - -#if defined THUMBSTICK_DEBUG - rawX = 0; - rawY = 0; - distX = 0; - distY = 0; - thumbstickLogTimer = 0; -#endif -} - -// Axis-level wrapper to read raw value and return signed distanced from center -int8_t thumbstick_get_component(uint8_t pin) { - int16_t value = analogReadPin(pin); // range of [0 to 1023] -#if defined THUMBSTICK_DEBUG - if (pin == THUMBSTICK_PIN_X) { - rawX = value; - distX = value - THUMBSTICK_RANGE_CENTER; - } else { - rawY = value; - distY = value - THUMBSTICK_RANGE_CENTER; - } -#endif - return (value - THUMBSTICK_RANGE_CENTER) / 4; -} - -thumbstick_mode_t thumbstick_mode_get(void) { return thumbstick_state.config.mode; } -thumbstick_vector_t thumbstick_vector_get(void) { return thumbstick_state.vector; } -void thumbstick_mode_set(thumbstick_mode_t mode) { thumbstick_state.config.mode = mode; } -void thumbstick_vector_set(thumbstick_vector_t vector) { thumbstick_state.vector = vector; } - -void thumbstick_mode_cycle_forward(void) { thumbstick_mode_set(addmod8(thumbstick_mode_get(), 1, _THUMBSTICK_MODE_LAST)); } -void thumbstick_mode_cycle_backward(void) { thumbstick_mode_set(submod8(thumbstick_mode_get(), 1, _THUMBSTICK_MODE_LAST)); } - -// Get mouse speed -int8_t thumbstick_get_mouse_speed(int8_t component) { - uint8_t distance = abs(component); - uint8_t speed = ((distance > THUMBSTICK_FINE_ZONE) * THUMBSTICK_SPEED) + (((distance <= THUMBSTICK_FINE_ZONE) && (distance > THUMBSTICK_DEAD_ZONE)) * THUMBSTICK_FINE_SPEED); - return ((component < 0) * -1 + (component > 0)) * lerp8by8(0, speed, distance * 2); -} - -// Fix direction within one of 8 axes (or 4 if 8-axis is disabled) -thumbstick_direction_t thumbstick_get_discretized_direction(thumbstick_vector_t vector, bool eightAxis) { - thumbstick_direction_t direction; - uint8_t absX = abs(vector.x); - uint8_t absY = abs(vector.y); - uint8_t maxComponent = (absX * (absX > absY)) + (absY * (absX <= absY)); - bool insideDeadZone = (maxComponent <= THUMBSTICK_DEAD_ZONE); - bool outsideDiagonalZone = (abs(absX - absY) >= THUMBSTICK_AXIS_SEPARATION); - bool dominantY = (absY >= absX); - - // Branchless code for these conditions: - // - Set all to false inside a deadzone - // - Otherwise, if outside the diagonal zone or eight axis is disabled, set only the dominant direction (either vertical or horizontal) - direction.up = (!insideDeadZone) && (vector.y < 0) && (!((outsideDiagonalZone || !eightAxis) && !dominantY)); - direction.down = (!insideDeadZone) && (vector.y > 0) && (!((outsideDiagonalZone || !eightAxis) && !dominantY)); - direction.left = (!insideDeadZone) && (vector.x < 0) && (!((outsideDiagonalZone || !eightAxis) && dominantY)); - direction.right = (!insideDeadZone) && (vector.x > 0) && (!((outsideDiagonalZone || !eightAxis) && dominantY)); - return direction; -} - -void thumbstick_read_vectors(void) { - thumbstickTimer = timer_read(); -#ifndef THUMBSTICK_FLIP_X - thumbstick_state.vector.x = thumbstick_get_component(THUMBSTICK_PIN_X); -#else - thumbstick_state.vector.x = -thumbstick_get_component(THUMBSTICK_PIN_X); -#endif -#ifndef THUMBSTICK_FLIP_Y - thumbstick_state.vector.y = thumbstick_get_component(THUMBSTICK_PIN_Y); -#else - thumbstick_state.vector.y = -thumbstick_get_component(THUMBSTICK_PIN_Y); -#endif -} - -void thumbstick_calculate_state(void) { - switch (thumbstick_state.config.mode) { - case THUMBSTICK_MODE_MOUSE: - thumbstick_state.report.x = thumbstick_get_mouse_speed(thumbstick_state.vector.x); - thumbstick_state.report.y = thumbstick_get_mouse_speed(thumbstick_state.vector.y); - break; - case THUMBSTICK_MODE_ARROWS: - thumbstick_state.direction = thumbstick_get_discretized_direction(thumbstick_state.vector, THUMBSTICK_EIGHT_AXIS); - break; - case THUMBSTICK_MODE_SCROLL: - if (timer_elapsed(thumbstickScrollTimer) > THUMBSTICK_SCROLL_TIMEOUT) { - thumbstick_direction_t scrollDirection; - thumbstickScrollTimer = timer_read(); - scrollDirection = thumbstick_get_discretized_direction(thumbstick_state.vector, false); - - thumbstick_state.report.v = (scrollDirection.up + (scrollDirection.down * -1)) * THUMBSTICK_SCROLL_SPEED; - thumbstick_state.report.h = (scrollDirection.right + (scrollDirection.left * -1)) * THUMBSTICK_SCROLL_SPEED; - } else { - thumbstick_state.report.v = thumbstick_state.report.h = 0; - } - break; - default: - break; - } -} - -void thumbstick_process_state(report_mouse_t* report) { - switch (thumbstick_state.config.mode) { - case THUMBSTICK_MODE_MOUSE: - report->x = thumbstick_state.report.x; - report->y = thumbstick_state.report.y; -#ifdef THUMBSTICK_DEBUG - if (timer_elapsed(thumbstickLogTimer) > 100) { - thumbstickLogTimer = timer_read(); - uprintf("Raw (%d, %d); Dist (%d, %d); Vec (%d, %d); Mouse (%d, %d);\n", rawX, rawY, distX, distY, thumbstick_state.vector.x, thumbstick_state.vector.y, thumbstick_state.report.x, thumbstick_state.report.y); - } -#endif - break; - case THUMBSTICK_MODE_ARROWS: - update_keycode_status(KC_UP, thumbstick_state.lastDirection.up, thumbstick_state.direction.up); - update_keycode_status(KC_DOWN, thumbstick_state.lastDirection.down, thumbstick_state.direction.down); - update_keycode_status(KC_LEFT, thumbstick_state.lastDirection.left, thumbstick_state.direction.left); - update_keycode_status(KC_RIGHT, thumbstick_state.lastDirection.right, thumbstick_state.direction.right); - thumbstick_state.lastDirection = thumbstick_state.direction; -#ifdef THUMBSTICK_DEBUG - if (timer_elapsed(thumbstickLogTimer) > 100) { - thumbstickLogTimer = timer_read(); - uprintf("Up %d; Down %d; Left: %d; Right %d; Vec (%d, %d);\n", thumbstick_state.direction.up, thumbstick_state.direction.down, thumbstick_state.direction.left, thumbstick_state.direction.right, thumbstick_state.vector.x, thumbstick_state.vector.y); - } -#endif - break; - case THUMBSTICK_MODE_SCROLL: - report->v = thumbstick_state.report.v; - report->h = thumbstick_state.report.h; -#ifdef THUMBSTICK_DEBUG - if (timer_elapsed(thumbstickLogTimer) > 100) { - thumbstickLogTimer = timer_read(); - uprintf("Vec (%d, %d); Scroll (%d, %d);\n", thumbstick_state.vector.x, thumbstick_state.vector.y, thumbstick_state.report.v, thumbstick_state.report.h); - } -#endif - break; - default: - break; - } -} - -void update_keycode_status(uint16_t keycode, bool last, bool current) { - if (last != current) { - if (current) { - register_code16(keycode); - } else { - unregister_code16(keycode); - } - } -} - -void pointing_device_init(void) { thumbstick_init(); } - -void pointing_device_task(void) { - if (timer_elapsed(thumbstickTimer) > THUMBSTICK_TIMEOUT) { - report_mouse_t report = pointing_device_get_report(); - - thumbstick_read_vectors(); - // Calculate and process thumbstick state (if master half doesn't have the thumbstick, the custom transport will bring the vectors over) - thumbstick_calculate_state(); - thumbstick_process_state(&report); - - pointing_device_set_report(report); - pointing_device_send(); - } -} \ No newline at end of file diff --git a/keyboards/barobord/thumbstick.h b/keyboards/barobord/thumbstick.h deleted file mode 100644 index fdf3f8a36d..0000000000 --- a/keyboards/barobord/thumbstick.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -typedef enum { - THUMBSTICK_MODE_MOUSE = 0, - THUMBSTICK_MODE_ARROWS, - THUMBSTICK_MODE_SCROLL, - _THUMBSTICK_MODE_LAST // Do not use, except for looping through enum values -} thumbstick_mode_t; - -// Parameters -#define THUMBSTICK_DEAD_ZONE 15 // Values below this are ignored (deadzone) -#define THUMBSTICK_FINE_ZONE 40 // Values below this enable fine movement - -#define THUMBSTICK_MODE THUMBSTICK_MODE_MOUSE -#define THUMBSTICK_SPEED 40 // Range [0 - 127] -#define THUMBSTICK_FINE_SPEED 20 -#define THUMBSTICK_SCROLL_SPEED 1 - -#define THUMBSTICK_EIGHT_AXIS true -#define THUMBSTICK_AXIS_SEPARATION 24 // range [0 - 127], angle away from diagonals - -// Implicit and derived constants -#define THUMBSTICK_TIMEOUT 10 // Mouse report throttling time in ms -#define THUMBSTICK_SCROLL_TIMEOUT 200 // Mouse scroll throttling time in ms -#define THUMBSTICK_RANGE_START 0 -#define THUMBSTICK_RANGE_STOP 1023 -#define THUMBSTICK_RANGE_CENTER (THUMBSTICK_RANGE_STOP - THUMBSTICK_RANGE_START + 1) / 2 -#define THUMBSTICK_RANGE_MOVEMENT (THUMBSTICK_RANGE_CENTER - THUMBSTICK_DEAD_ZONE) -#if THUMBSTICK_SPEED > 127 -# undef THUMBSTICK_SPEED -# define THUMBSTICK_SPEED 127 -#endif - -#include "timer.h" -#include "analog.h" -#include "pointing_device.h" -#include "lib/lib8tion/lib8tion.h" - -#if defined THUMBSTICK_DEBUG -# include "print.h" -uint16_t rawX; -uint16_t rawY; -uint16_t distX; -uint16_t distY; -uint16_t thumbstickLogTimer; -#endif - -typedef struct { - thumbstick_mode_t mode; -} thumbstick_config_t; - -typedef struct { - int16_t x; - int16_t y; -} thumbstick_vector_t; - -typedef struct { - bool up; - bool right; - bool down; - bool left; -} thumbstick_direction_t; - -typedef struct { - thumbstick_config_t config; - thumbstick_vector_t vector; - thumbstick_direction_t direction; - thumbstick_direction_t lastDirection; - report_mouse_t report; -} thumbstick_state_t; - -uint16_t thumbstickTimer; -uint16_t thumbstickScrollTimer; - -thumbstick_state_t thumbstick_state; - -void thumbstick_mode_set(thumbstick_mode_t mode); -void thumbstick_vector_set(thumbstick_vector_t vector); - -thumbstick_mode_t thumbstick_mode_get(void); -thumbstick_vector_t thumbstick_vector_get(void); - -void thumbstick_mode_cycle_forward(void); -void thumbstick_mode_cycle_backward(void); - -void thumbstick_init(void); - -// Axis-level wrapper to read raw value, do logging and calculate speed -int8_t thumbstick_get_component(uint8_t pin); - -// Get mouse speed -int8_t thumbstick_get_mouse_speed(int8_t component); - -// Fix direction within one of 8 axes (or 4 if 8-axis is disabled) -thumbstick_direction_t thumbstick_get_discretized_direction(thumbstick_vector_t vector, bool eightAxis); - -// Read analog values into vectors -void thumbstick_read_vectors(void); - -// Perform actions based on state -void thumbstick_process_state(report_mouse_t*); - -void update_keycode_status(uint16_t keycode, bool last, bool current); \ No newline at end of file diff --git a/keyboards/euclid36/keymaps/sadekbaroudi/keymap.c b/keyboards/euclid36/keymaps/sadekbaroudi/keymap.c index 61575483cb..2accf948d0 100644 --- a/keyboards/euclid36/keymaps/sadekbaroudi/keymap.c +++ b/keyboards/euclid36/keymaps/sadekbaroudi/keymap.c @@ -47,7 +47,7 @@ K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \ LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \ K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE, K2A), \ - KC_MUTE, KC_LEAD, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT, LCTL(KC_BSPC) \ + KC_MUTE, KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT, LCTL(KC_BSPC) \ ) /* Re-pass though to allow templates to be used */ diff --git a/keyboards/euclid36proto/keymaps/sadekbaroudi/keymap.c b/keyboards/euclid36proto/keymaps/sadekbaroudi/keymap.c index 9a1276d696..04ad6681d0 100644 --- a/keyboards/euclid36proto/keymaps/sadekbaroudi/keymap.c +++ b/keyboards/euclid36proto/keymaps/sadekbaroudi/keymap.c @@ -40,7 +40,7 @@ K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \ LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \ K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE, K2A), \ - KC_LEAD, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \ + KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \ ) /* Re-pass though to allow templates to be used */ diff --git a/keyboards/handwired/barobordhw/keymaps/sadekbaroudi/keymap.c b/keyboards/handwired/barobordhw/keymaps/sadekbaroudi/keymap.c index 83cb0d9116..e32a5e69f4 100644 --- a/keyboards/handwired/barobordhw/keymaps/sadekbaroudi/keymap.c +++ b/keyboards/handwired/barobordhw/keymaps/sadekbaroudi/keymap.c @@ -40,7 +40,7 @@ K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \ LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \ K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE, K2A), \ - _______, _______, KC_LEAD, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT, _______, _______ \ + _______, _______, KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT, _______, _______ \ ) /* Re-pass though to allow templates to be used */ diff --git a/keyboards/handwired/enigma36/keymaps/sadekbaroudi/keymap.c b/keyboards/handwired/enigma36/keymaps/sadekbaroudi/keymap.c index d4e3a1583c..f4f0fb069f 100644 --- a/keyboards/handwired/enigma36/keymaps/sadekbaroudi/keymap.c +++ b/keyboards/handwired/enigma36/keymaps/sadekbaroudi/keymap.c @@ -40,7 +40,7 @@ K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \ LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \ K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE, K2A), \ - KC_LEAD, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \ + KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \ ) /* Re-pass though to allow templates to be used */ diff --git a/keyboards/handwired/pteron38/keymaps/sadekbaroudi/keymap.c b/keyboards/handwired/pteron38/keymaps/sadekbaroudi/keymap.c index 88df8fc6ed..c4358a2c42 100644 --- a/keyboards/handwired/pteron38/keymaps/sadekbaroudi/keymap.c +++ b/keyboards/handwired/pteron38/keymaps/sadekbaroudi/keymap.c @@ -40,7 +40,7 @@ K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \ LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \ K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE,K2A), \ - KC_LEAD, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), _______, _______, LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \ + KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), _______, _______, LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \ ) /* Re-pass though to allow templates to be used */ diff --git a/users/sadekbaroudi/pimoroni_trackball.c b/users/sadekbaroudi/pimoroni_trackball.c new file mode 100644 index 0000000000..6303ff817c --- /dev/null +++ b/users/sadekbaroudi/pimoroni_trackball.c @@ -0,0 +1,329 @@ +#include "pimoroni_trackball.h" +#include "i2c_master.h" +#include "pointing_device.h" + +#ifndef TRACKBALL_NO_MATH +#include "math.h" +# ifndef TRACKBALL_ANGLE_OFFSET +# define TRACKBALL_ANGLE_OFFSET 0 +# endif +#endif + +#undef TRACKBALL_REVERSE_VSCROLL +#undef TRACKBALL_REVERSE_HSCROLL + +#ifndef TRACKBALL_ORIENTATION +# define TRACKBALL_ORIENTATION 0 +#endif + +#ifndef TRACKBALL_REVERSE_VSCROLL +# define TRACKBALL_REVERSE_VSCROLL false +#endif + +#ifndef TRACKBALL_REVERSE_HSCROLL +# define TRACKBALL_REVERSE_HSCROLL false +#endif + +#ifndef TRACKBALL_ACCELERATION_WINDOW +# define TRACKBALL_ACCELERATION_WINDOW 50000 // ms window to increase acceleration factor +#endif + +// Sadek: I commented this line out, as I don't have the interrupt pin connected +//#define TRACKBALL_INTERRUPT_PIN D3 +#define TRACKBALL_TIMEOUT 5 + +bool scrolling = false; +bool trackball_idle = true; +uint8_t tb_brightness = 42; + + +void trackball_init(void) { + i2c_init(); +#ifdef TRACKBALL_INTERRUPT_PIN + setPinInput(TRACKBALL_INTERRUPT_PIN); + writePinLow(TRACKBALL_INTERRUPT_PIN); + uint8_t data[] = {REG_INTERRUPT_PIN, MASK_INTERRUPT_PIN_ENABLE}; + i2c_transmit(TRACKBALL_WRITE, data, 2, TB_I2C_TIMEOUT); +#endif +} + +bool trackball_get_interrupt(void) { +#ifndef TRACKBALL_INTERRUPT_PIN + uint8_t data[1] = {}; + i2c_readReg(TRACKBALL_WRITE, REG_INTERRUPT_PIN, data, 1, TB_I2C_TIMEOUT); + + return data[0] & MASK_INTERRUPT_TRIGGERED; +#else + return !readPin(TRACKBALL_INTERRUPT_PIN); +#endif +} + +void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { + uint8_t data[] = {0x00, red, green, blue, white}; + i2c_transmit(TRACKBALL_WRITE, data, 5, TB_I2C_TIMEOUT); +} + +void trackball_read_state(uint8_t* data, uint16_t size_of_data) { + i2c_readReg(TRACKBALL_WRITE, REG_LEFT, data, size_of_data, TB_I2C_TIMEOUT); +} + +void trackball_set_scrolling(bool scroll) { + scrolling = scroll; +} + +trackball_state_t trackball_get_state(void) { + // up down left right button + uint8_t s[5] = {}; + trackball_read_state(s, 5); + + trackball_state_t state = { +#if TRACKBALL_ORIENTATION == 0 + // Pimoroni text is up + .y = s[0] - s[1], + .x = s[3] - s[2], +#elif TRACKBALL_ORIENTATION == 1 + // Pimoroni text is right + .y = s[3] - s[2], + .x = s[1] - s[0], +#elif TRACKBALL_ORIENTATION == 2 + // Pimoroni text is down + .y = s[1] - s[0], + .x = s[2] - s[3], +#else + // Pimoroni text is left + .y = s[2] - s[3], + .x = s[0] - s[1], +#endif + .button_down = s[4] & 0x80, + .button_triggered = s[4] & 0x01, + }; + +#ifndef TRACKBALL_NO_MATH + state.angle_rad = atan2(state.y, state.x) + TRACKBALL_ANGLE_OFFSET; + state.vector_length = sqrt(pow(state.x, 2) + pow(state.y, 2)); + state.raw_x = state.x; + state.raw_y = state.y; + state.x = (int16_t)(state.vector_length * cos(state.angle_rad)); + state.y = (int16_t)(state.vector_length * sin(state.angle_rad)); +#endif + + return state; +} + +void trackball_sleep(void) { + /* not sure how this is supposed to work */ + uint8_t data[] = {REG_CTRL, MSK_CTRL_FWRITE | MSK_CTRL_SLEEP}; + i2c_transmit(TRACKBALL_WRITE, data, 2, TB_I2C_TIMEOUT); +} + +void trackball_set_brightness(uint8_t brightness) { + uint8_t data[4] = {}; + i2c_readReg(TRACKBALL_WRITE, REG_RED, data, 4, TB_I2C_TIMEOUT); + for (int i=0; i<4; i++) { + if (data[i]) { + data[i] = brightness; + } + } + i2c_writeReg(TRACKBALL_WRITE, REG_RED, data, 4, TB_I2C_TIMEOUT); +} + +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +void trackball_set_hsv(uint8_t hue, uint8_t sat, uint8_t brightness) { + RGB rgb = hsv_to_rgb((HSV){hue, sat, brightness}); + uint8_t white = MIN(rgb.r, MIN(rgb.g, rgb.b)); + rgb.r -= white; + rgb.g -= white; + rgb.b -= white; + + trackball_set_rgbw(rgb.r, rgb.g, rgb.b, white); +} + + +__attribute__((weak)) void pointing_device_init(void) { + trackball_init(); + trackball_set_rgbw(0,0,tb_brightness,0); +} + + +__attribute__((weak)) void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y, int16_t h, int16_t v) { + mouse_report->x = x; + mouse_report->y = y; + mouse_report->h = h; + mouse_report->v = v; +} +__attribute__((weak)) void update_member(int8_t* member, int16_t* offset) { + if (*offset > 127) { + *member = 127; + *offset -= 127; + } else if (*offset < -127) { + *member = -127; + *offset += 127; + } else { + *member = *offset; + *offset = 0; + } +} + +__attribute__((weak)) bool has_report_changed(report_mouse_t new, report_mouse_t old) { + return (new.buttons != old.buttons) || + (new.x && new.x != old.x) || + (new.y && new.y != old.y) || + (new.h && new.h != old.h) || + (new.v && new.v != old.v); +} + +static int16_t x_offset = 0; +static int16_t y_offset = 0; +static int16_t v_offset = 0; +static int16_t h_offset = 0; +static int16_t tb_timer = 0; +uint16_t acceleration_timer = 0; + +__attribute__((weak)) void process_mouse(report_mouse_t* mouse, bool fast_scroll) { + static int8_t new_x_offset = 0; + static int8_t new_y_offset = 0; + static int8_t new_v_offset = 0; + static int8_t new_h_offset = 0; + if (trackball_get_interrupt() && (!tb_timer || timer_elapsed(tb_timer) > TRACKBALL_TIMEOUT)) { + tb_timer = timer_read() | 1; + + trackball_state_t state = trackball_get_state(); + + if (state.button_triggered) { + if(state.button_down) { + mouse->buttons |= MOUSE_BTN1; + } else { + mouse->buttons &= ~MOUSE_BTN1; + } + } else { + + + //-------------------------------------------------------------- + //DONT WANT TO MOVE THESE BUT HERE THEY ARE + //-------------------------------------------------------------- + float power = 2.5; + float var_accel = 1; + if (fast_scroll) { + var_accel = 2; + power = 3; + } + double newlen = pow(state.vector_length*var_accel, power); + + //float var_accel = 2; //acceleration factor + //double newlen = pow(state.vector_length, power); + + /* + if (state.vector_length > 3 && (timer_elapsed(acceleration_timer) == 0 || timer_elapsed(acceleration_timer) < TRACKBALL_ACCELERATION_WINDOW)) { + acceleration_timer = timer_read(); + newlen += pow(state.vector_length*var_accel, power); + } else { + acceleration_timer = timer_read(); + newlen += pow(state.vector_length, power); + } + */ + //newlen = pow(state.vector_length, power); + + x_offset += (newlen * cos(state.angle_rad)); + y_offset += (newlen * sin(state.angle_rad)); + + + /* + float y_correction = 0.8; + if ( y_offset > 0 && ((newlen * sin(state.angle_rad) * y_correction == 0)) { + y_offset = 0.2; + } + else { + y_offset *= y_correction; + } + */ + + #if TRACKBALL_REVERSE_VSCROLL == true + v_offset += (newlen * sin(state.angle_rad)); + #else + v_offset -= (newlen * sin(state.angle_rad)); + #endif + #if TRACKBALL_REVERSE_HSCROLL == true + h_offset -= (newlen * cos(state.angle_rad)); + #else + h_offset += (newlen * cos(state.angle_rad)); + #endif + } + + } + + while (x_offset || y_offset || h_offset || v_offset) { + update_member(&new_x_offset, &x_offset); + update_member(&new_y_offset, &y_offset); + + update_member(&new_v_offset, &v_offset); + update_member(&new_h_offset, &h_offset); + + mouse->x = new_x_offset; + mouse->y = new_y_offset; + mouse->v = new_v_offset; + mouse->h = new_h_offset; + } +} + +__attribute__((weak)) void pointing_device_task(void) { + report_mouse_t mouse_report = pointing_device_get_report(); + + // look into whether or not I'd want this + //bool fast_scroll = (get_highest_layer(layer_state) == _SYMBOLS); + bool fast_scroll = false; + process_mouse(&mouse_report, fast_scroll); + + // Logic for colors is in rgb_stuff.c + // Note that for now, if RGBLIGHT_ENABLE is not set, this won't run, so they are tied together, I can fix later + + // If I ever want to use scrolling, set the rules here + /* + if (false && layer_state_is(_NAVIGATION)) { + trackball_set_scrolling(true); + } else { + trackball_set_scrolling(false); + } + */ + + pointing_device_set_report(mouse_report); + pointing_device_send(); +} + +__attribute__((weak)) void pointing_device_send(void) { + static report_mouse_t old_report = {}; + report_mouse_t mouseReport = pointing_device_get_report(); + if (is_keyboard_master()) { + int8_t x = mouseReport.x, y = mouseReport.y, h = mouseReport.h, v = mouseReport.v; + mouseReport.x = 0; + mouseReport.y = 0; + mouseReport.h = 0; + mouseReport.v = 0; + if (!scrolling) { + process_mouse_user(&mouseReport, x, y, 0, 0); + } else { + process_mouse_user(&mouseReport, 0, 0, h, v); + } + + if (has_report_changed(mouseReport, old_report)) { + trackball_idle = false; + host_mouse_send(&mouseReport); + } else { + trackball_idle = true; + } + } else { + if (has_report_changed(mouseReport, old_report)) { + trackball_idle = false; + } else { + trackball_idle = true; + } + + } + mouseReport.x = 0; + mouseReport.y = 0; + mouseReport.v = 0; + mouseReport.h = 0; + old_report = mouseReport; + pointing_device_set_report(mouseReport); +} \ No newline at end of file diff --git a/users/sadekbaroudi/pimoroni_trackball.h b/users/sadekbaroudi/pimoroni_trackball.h new file mode 100644 index 0000000000..8eccff6431 --- /dev/null +++ b/users/sadekbaroudi/pimoroni_trackball.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include "color.h" + +#ifndef TRACKBALL_ADDRESS +# define TRACKBALL_ADDRESS 0x0A +#endif + +#ifndef TRACKBALL_ANGLE_OFFSET +# define TRACKBALL_ANGLE_OFFSET 0 +#endif + +#define TRACKBALL_WRITE ((TRACKBALL_ADDRESS << 1) | I2C_WRITE) +#define TRACKBALL_READ ((TRACKBALL_ADDRESS << 1) | I2C_READ) + +#define TB_I2C_TIMEOUT 100 + +#define REG_RED 0x00 +#define REG_GREEN 0x01 +#define REG_BLUE 0x02 +#define REG_WHITE 0x03 + +#define REG_LEFT 0x04 + +#define REG_INTERRUPT_PIN 0xF9 +#define MASK_INTERRUPT_TRIGGERED 0x01 +#define MASK_INTERRUPT_PIN_ENABLE 0x02 + +#define REG_CTRL 0xFE +#define MSK_CTRL_SLEEP 0b00000001 +#define MSK_CTRL_RESET 0b00000010 +#define MSK_CTRL_FREAD 0b00000100 +#define MSK_CTRL_FWRITE 0b00001000 + + +typedef struct { + int16_t x; + int16_t y; + bool button_down; + bool button_triggered; +#ifndef TRACKBALL_NO_MATH + double vector_length; + double angle_rad; + int8_t raw_x; + int8_t raw_y; +#endif +} trackball_state_t; + +void trackball_init(void); +bool trackball_get_interrupt(void); +void trackball_set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w); +void trackball_read_state(uint8_t* data, uint16_t size_of_data); +void trackball_sleep(void); +void trackball_set_brightness(uint8_t brightness); +void trackball_set_hsv(uint8_t hue, uint8_t sat, uint8_t brightness); +void trackball_set_scrolling (bool scroll); + +trackball_state_t trackball_get_state(void); + +void pointing_device_init(void); +void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y, int16_t h, int16_t v); +void update_member(int8_t* member, int16_t* offset); +bool has_report_changed(report_mouse_t new, report_mouse_t old); +void process_mouse(report_mouse_t* mouse, bool fast_scroll); +void pointing_device_task(void); +void pointing_device_send(void); \ No newline at end of file diff --git a/users/sadekbaroudi/process_records.c b/users/sadekbaroudi/process_records.c index f1f5094bea..0262a13e99 100755 --- a/users/sadekbaroudi/process_records.c +++ b/users/sadekbaroudi/process_records.c @@ -11,11 +11,13 @@ __attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t // Defines actions tor my global custom keycodes. Defined in sadekbaroudi.h file // Then runs the _keymap's record handler if not processed here bool process_record_user(uint16_t keycode, keyrecord_t *record) { + #ifdef CASEMODES_ENABLE // Process case modes if (!process_case_modes(keycode, record)) { return false; } // If console is enabled, it will print the matrix position and status of each key pressed + #endif #ifdef KEYLOGGER_ENABLE # if defined(KEYBOARD_ergodox_ez) || defined(KEYBOARD_keebio_iris_rev2) xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.row, record->event.key.col, record->event.pressed); @@ -182,23 +184,31 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { case C_CAPSWORD: // NOTE: if you change this behavior, may want to update in keymap.c for COMBO behavior if (record->event.pressed) { + #ifdef CASEMODES_ENABLE enable_caps_word(); + #endif } break; case C_HYPHENCASE: + #ifdef CASEMODES_ENABLE if (record->event.pressed) { enable_xcase_with(KC_MINS); } + #endif break; case C_ANYCASE: + #ifdef CASEMODES_ENABLE if (record->event.pressed) { enable_xcase(); } + #endif break; case C_UNDERSCORECASE: + #ifdef CASEMODES_ENABLE if (record->event.pressed) { enable_xcase_with(KC_UNDS); } + #endif break; // COMMENT TO DISABLE MACROS case L_GREP: diff --git a/users/sadekbaroudi/rgb_stuff.c b/users/sadekbaroudi/rgb_stuff.c index 6bf1b2fbaf..7a0090c486 100755 --- a/users/sadekbaroudi/rgb_stuff.c +++ b/users/sadekbaroudi/rgb_stuff.c @@ -2,6 +2,10 @@ #include "rgb_stuff.h" #include "eeprom.h" +#ifdef PIMORONI_TRACKBALL_ENABLE +#include "pimoroni_trackball.h" +#endif + bool has_initialized; void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val(), index); } @@ -89,8 +93,14 @@ layer_state_t layer_state_set_rgb_light(layer_state_t state) { caps_lock_rgb_mode = CAPS_LOCK_RGB_MODE; #endif rgblight_set_hsv_and_mode(caps_lock_rgb_hue, 255, 255, caps_lock_rgb_mode); + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(caps_lock_rgb_hue, 255, 255); + #endif } else if (userspace_config.rgb_base_layer_override) { // If the base layer override is enabled, use that rgblight_set_hsv_and_mode(userspace_config.hue, userspace_config.sat, userspace_config.val, userspace_config.mode); + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(userspace_config.hue, userspace_config.sat, userspace_config.val); + #endif } else { // if base layer override is disabled, always show the base setting uint8_t base_layer_rgb_hue = 167; // BLUE uint8_t base_layer_rgb_mode = mode; @@ -101,33 +111,63 @@ layer_state_t layer_state_set_rgb_light(layer_state_t state) { base_layer_rgb_mode = BASE_LAYER_RGB_MODE; #endif rgblight_set_hsv_and_mode(base_layer_rgb_hue, 255, 255, base_layer_rgb_mode); + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(base_layer_rgb_hue, 255, 255); + #endif } break; case _QWERTY: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(10, 10, 255); // white + #endif rgblight_set_hsv_and_mode(10, 10, 255, mode); // white break; case _WORKMAN: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(HSV_MAGENTA); + #endif rgblight_set_hsv_and_mode(HSV_MAGENTA, mode); break; case _NAVIGATION: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(HSV_GREEN); + #endif rgblight_set_hsv_and_mode(HSV_GREEN, mode); break; case _SYMBOLS: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(HSV_PURPLE); + #endif rgblight_set_hsv_and_mode(HSV_PURPLE, mode); break; case _FUNCTION: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(HSV_YELLOW); + #endif rgblight_set_hsv_and_mode(HSV_YELLOW, mode); break; case _MOUSE: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(HSV_CYAN); + #endif rgblight_set_hsv_and_mode(HSV_CYAN, mode); break; case _MEDIA: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(16, 255, 255); // orange + #endif rgblight_set_hsv_and_mode(16, 255, 255, mode); // orange break; case _WINNAV: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(10, 10, 255); + #endif rgblight_set_hsv_and_mode(10, 10, 255, mode); // near-white break; default: + #ifdef PIMORONI_TRACKBALL_ENABLE + trackball_set_hsv(HSV_SPRINGGREEN); + #endif rgblight_set_hsv_and_mode(HSV_SPRINGGREEN, mode); break; } diff --git a/users/sadekbaroudi/rules.mk b/users/sadekbaroudi/rules.mk index 581da2d9c0..9c7d680ed7 100755 --- a/users/sadekbaroudi/rules.mk +++ b/users/sadekbaroudi/rules.mk @@ -10,15 +10,19 @@ NKRO_ENABLE = no RAW_ENABLE = no CASEMODES_ENABLE = yes COMBO_ENABLE = yes -LEADER_ENABLE = yes # UNCOMMENT TO DISABLE MACROS -# EXTRAFLAGS += -flto +#EXTRAFLAGS += -flto # UNCOMMENT TO DISABLE MACROS SPACE_CADET_ENABLE = no GRAVE_ESC_ENABLE = no +# define this in the keyboard's rules.mk +#PIMORONI_TRACKBALL_ENABLE = yes + + + ifneq ($(strip $(NO_SECRETS)), yes) ifneq ("$(wildcard $(USER_PATH)/secrets.c)","") SRC += secrets.c @@ -40,7 +44,6 @@ ifneq ($(strip $(RGB_MATRIX_ENABLE)), no) SRC += rgb_matrix_stuff.c endif - ifdef CONSOLE_ENABLE ifeq ($(strip $(KEYLOGGER_ENABLE)), yes) OPT_DEFS += -DKEYLOGGER_ENABLE @@ -57,4 +60,10 @@ endif ifeq ($(strip $(COMBO_ENABLE)), yes) SRC += combos.c +endif + +ifeq ($(strip $(PIMORONI_TRACKBALL_ENABLE)), yes) + POINTING_DEVICE_ENABLE := yes + SRC += pimoroni_trackball.c + OPT_DEFS += -DPIMORONI_TRACKBALL_ENABLE endif \ No newline at end of file diff --git a/users/sadekbaroudi/sadekbaroudi.c b/users/sadekbaroudi/sadekbaroudi.c index 22db6ce618..46bdb2f5fb 100755 --- a/users/sadekbaroudi/sadekbaroudi.c +++ b/users/sadekbaroudi/sadekbaroudi.c @@ -259,4 +259,3 @@ bool hasAllBitsInMask(uint8_t value, uint8_t mask) { return (value & mask) == mask; } - diff --git a/users/sadekbaroudi/wrappers.h b/users/sadekbaroudi/wrappers.h index 80c90efcf0..6425ed5422 100755 --- a/users/sadekbaroudi/wrappers.h +++ b/users/sadekbaroudi/wrappers.h @@ -54,6 +54,11 @@ expanded before being used as arguments to the LAYOUT_xxx macro. # define LAYOUT LAYOUT_barobord #endif +// Since barobord uses the name LAYOUT_barobord instead of LAYOUT +#if (!defined(LAYOUT) && defined(LAYOUT_ortho_4x12)) +# define LAYOUT LAYOUT_ortho_4x12 +#endif + // clang-format off #define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__)