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__)