diff --git a/drivers/sensors/pmw3320.c b/drivers/sensors/pmw3320.c index a4648ef425b0..224e37df211f 100644 --- a/drivers/sensors/pmw3320.c +++ b/drivers/sensors/pmw3320.c @@ -22,14 +22,66 @@ #include "debug.h" #include "gpio.h" -void pmw3320_init(void) { +typedef enum { + PMW3320_REG_Product_ID = 0x00, + PMW3320_REG_Revision_ID = 0x01, + PMW3320_REG_Motion = 0x02, + PMW3320_REG_Delta_X = 0x03, + PMW3320_REG_Delta_Y = 0x04, + PMW3320_REG_SQUAL = 0x05, + PMW3320_REG_Shutter_Upper = 0x06, + PMW3320_REG_Shutter_Lower = 0x07, + PMW3320_REG_Maximum_Pixel = 0x08, + PMW3320_REG_Pixel_Accum = 0x09, + PMW3320_REG_Minimum_Pixel = 0x0a, + PMW3320_REG_Pixel_Grab = 0x0b, + PMW3320_REG_Delta_XY = 0x0c, + PMW3320_REG_Resolution = 0x0d, + PMW3320_REG_Run_Downshift = 0x0e, + PMW3320_REG_Rest1_Period = 0x0f, + PMW3320_REG_Rest1_Downshift = 0x10, + PMW3320_REG_Rest2_Preiod = 0x11, + PMW3320_REG_Rest2_Downshift = 0x12, + PMW3320_REG_Rest3_Period = 0x13, + PMW3320_REG_Min_SQ_Run = 0x17, + PMW3320_REG_Axis_Control = 0x1a, + PMW3320_REG_Performance = 0x22, + PMW3320_REG_Low_Motion_Jitter = 0x23, + PMW3320_REG_Shutter_Max_HI = 0x36, + PMW3320_REG_Shutter_Max_LO = 0x37, + PMW3320_REG_Frame_Rate = 0x39, + PMW3320_REG_Power_Up_Reset = 0x3a, + PMW3320_REG_Shutdown = 0x3b, + PMW3320_REG_Inverse_Revision_ID = 0x3f, + PMW3320_REG_Led_Control = 0x40, + PMW3320_REG_Motion_Control = 0x41, + PMW3320_REG_Burst_Read_First = 0x42, + PMW3320_REG_Rest_Mode_Status = 0x45, + PMW3320_REG_Inverse_Product_ID = 0x4f, + PMW3320_REG_Motion_Burst = 0x63, +} pmw3320_regs; + +const pointing_device_driver_t pmw3320_driver_default = {.init = pmw3320_init, .get_report = pmw3320_get_report, .set_cpi = pmw3320_set_cpi, .get_cpi = pmw3320_get_cpi}; +#if defined(PMW3320_SCLK_PIN) & defined(PMW3320_SDIO_PIN) & defined(PMW3320_CS_PIN) +const pointing_device_3wire_spi_config_t pmw3320_config_default = {.cs = PMW3320_CS_PIN, .sclk = PMW3320_SCLK_PIN, .sdio = PMW3320_SDIO_PIN}; +#endif + +void pmw3320_sync(pin_t cs); +uint8_t pmw3320_serial_read(pointing_device_3wire_spi_config_t* pmw3320_config); +void pmw3320_serial_write(pointing_device_3wire_spi_config_t* pmw3320_config, uint8_t data); +uint8_t pmw3320_read_reg(pointing_device_3wire_spi_config_t* pmw3320_config, pmw3320_regs reg_addr); +void pmw3320_write_reg(pointing_device_3wire_spi_config_t* pmw3320_config, pmw3320_regs reg_addr, uint8_t data); +report_pmw3320_t pmw3320_read_burst(pointing_device_3wire_spi_config_t* pmw3320_config); + +void pmw3320_init(const void* config) { + pointing_device_3wire_spi_config_t* pmw3320_config = (pointing_device_3wire_spi_config_t*)config; // Initialize sensor serial pins. - setPinOutput(PMW3320_SCLK_PIN); - setPinOutput(PMW3320_SDIO_PIN); - setPinOutput(PMW3320_CS_PIN); + setPinOutput(pmw3320_config->sclk); + setPinOutput(pmw3320_config->sdio); + setPinOutput(pmw3320_config->cs); // reboot the sensor. - pmw3320_write_reg(REG_Power_Up_Reset, 0x5a); + pmw3320_write_reg(pmw3320_config, PMW3320_REG_Power_Up_Reset, 0x5a); // wait maximum time before sensor is ready. // this ensures that the sensor is actually ready after reset. @@ -38,66 +90,66 @@ void pmw3320_init(void) { // read a burst from the sensor and then discard it. // gets the sensor ready for write commands // (for example, setting the dpi). - pmw3320_read_burst(); + pmw3320_read_burst(pmw3320_config); // Pretty sure that this shouldn't be in the driver. // Probably device specific? // Set rest mode to default - pmw3320_write_reg(REG_Rest_Mode_Status, 0x00); + pmw3320_write_reg(pmw3320_config, PMW3320_REG_Rest_Mode_Status, 0x00); // Set LED to be always on - pmw3320_write_reg(REG_Led_Control, 0x4); + pmw3320_write_reg(pmw3320_config, PMW3320_REG_Led_Control, 0x4); // Disable rest mode - pmw3320_write_reg(REG_Performance, 0x80); + pmw3320_write_reg(pmw3320_config, PMW3320_REG_Performance, 0x80); } // Perform a synchronization with sensor. // Just as with the serial protocol, this is used by the slave to send a // synchronization signal to the master. -void pmw3320_sync(void) { - writePinLow(PMW3320_CS_PIN); +void pmw3320_sync(pin_t cs) { + writePinLow(cs); wait_us(1); - writePinHigh(PMW3320_CS_PIN); + writePinHigh(cs); } -void pmw3320_cs_select(void) { - writePinLow(PMW3320_CS_PIN); +void pmw3320_cs_select(pin_t cs) { + writePinLow(cs); } -void pmw3320_cs_deselect(void) { - writePinHigh(PMW3320_CS_PIN); +void pmw3320_cs_deselect(pin_t cs) { + writePinHigh(cs); } -uint8_t pmw3320_serial_read(void) { - setPinInput(PMW3320_SDIO_PIN); +uint8_t pmw3320_serial_read(pointing_device_3wire_spi_config_t* pmw3320_config) { + setPinInput(pmw3320_config->sdio); uint8_t byte = 0; for (uint8_t i = 0; i < 8; ++i) { - writePinLow(PMW3320_SCLK_PIN); + writePinLow(pmw3320_config->sclk); wait_us(1); - byte = (byte << 1) | readPin(PMW3320_SDIO_PIN); + byte = (byte << 1) | readPin(pmw3320_config->sdio); - writePinHigh(PMW3320_SCLK_PIN); + writePinHigh(pmw3320_config->sclk); wait_us(1); } return byte; } -void pmw3320_serial_write(uint8_t data) { - setPinOutput(PMW3320_SDIO_PIN); +void pmw3320_serial_write(pointing_device_3wire_spi_config_t* pmw3320_config, uint8_t data) { + setPinOutput(pmw3320_config->sdio); for (int8_t b = 7; b >= 0; b--) { - writePinLow(PMW3320_SCLK_PIN); + writePinLow(pmw3320_config->sclk); if (data & (1 << b)) - writePinHigh(PMW3320_SDIO_PIN); + writePinHigh(pmw3320_config->sdio); else - writePinLow(PMW3320_SDIO_PIN); + writePinLow(pmw3320_config->sdio); wait_us(2); - writePinHigh(PMW3320_SCLK_PIN); + writePinHigh(pmw3320_config->sclk); } // This was taken from ADNS5050 driver. @@ -112,12 +164,12 @@ void pmw3320_serial_write(uint8_t data) { } // Read a byte of data from a register on the sensor. -uint8_t pmw3320_read_reg(uint8_t reg_addr) { - pmw3320_cs_select(); +uint8_t pmw3320_read_reg(pointing_device_3wire_spi_config_t* pmw3320_config, pmw3320_regs reg_addr) { + pmw3320_cs_select(pmw3320_config->cs); - pmw3320_serial_write(reg_addr); + pmw3320_serial_write(pmw3320_config, reg_addr); - uint8_t byte = pmw3320_serial_read(); + uint8_t byte = pmw3320_serial_read(pmw3320_config); // This was taken directly from ADNS5050 driver... // tSRW & tSRR. See page 15 of the ADNS5050 spec sheet. @@ -126,67 +178,85 @@ uint8_t pmw3320_read_reg(uint8_t reg_addr) { // Honestly, this wait could probably be removed. wait_us(1); - pmw3320_cs_deselect(); + pmw3320_cs_deselect(pmw3320_config->cs); return byte; } -void pmw3320_write_reg(uint8_t reg_addr, uint8_t data) { - pmw3320_cs_select(); - pmw3320_serial_write(0b10000000 | reg_addr); - pmw3320_serial_write(data); - pmw3320_cs_deselect(); +void pmw3320_write_reg(pointing_device_3wire_spi_config_t* pmw3320_config, pmw3320_regs reg_addr, uint8_t data) { + pmw3320_cs_select(pmw3320_config->cs); + pmw3320_serial_write(pmw3320_config, 0b10000000 | reg_addr); + pmw3320_serial_write(pmw3320_config, data); + pmw3320_cs_deselect(pmw3320_config->cs); } -report_pmw3320_t pmw3320_read_burst(void) { - pmw3320_cs_select(); +report_pmw3320_t pmw3320_read_burst(pointing_device_3wire_spi_config_t* pmw3320_config) { + pmw3320_cs_select(pmw3320_config->cs); report_pmw3320_t data; data.dx = 0; data.dy = 0; - pmw3320_serial_write(REG_Motion_Burst); + pmw3320_serial_write(pmw3320_config, PMW3320_REG_Motion_Burst); - uint8_t x = pmw3320_serial_read(); - uint8_t y = pmw3320_serial_read(); + uint8_t x = pmw3320_serial_read(pmw3320_config); + uint8_t y = pmw3320_serial_read(pmw3320_config); // Probably burst mode may include contents of delta_xy register, // which contain HI parts of x/y deltas, but I had no luck finding it. // Probably it's required to activate 12-bit mode to access this data. // So we end burst mode early to not read unneeded information. - pmw3320_cs_deselect(); + pmw3320_cs_deselect(pmw3320_config->cs); - data.dx = convert_twoscomp(x); - data.dy = convert_twoscomp(y); + data.dx = paw3320_convert_twoscomp(x); + data.dy = paw3320_convert_twoscomp(y); return data; } // Convert a two's complement byte from an unsigned data type into a signed // data type. -int8_t convert_twoscomp(uint8_t data) { +int8_t paw3320_convert_twoscomp(uint8_t data) { if ((data & 0x80) == 0x80) return -128 + (data & 0x7F); else return data; } -uint16_t pmw3320_get_cpi(void) { - uint8_t cpival = pmw3320_read_reg(REG_Resolution); +uint16_t pmw3320_get_cpi(const void* config) { + pointing_device_3wire_spi_config_t* pmw3320_config = (pointing_device_3wire_spi_config_t*)config; + + uint8_t cpival = pmw3320_read_reg(pmw3320_config, PMW3320_REG_Resolution); // 0x1F is an inversion of 0x20 which is 0b100000 return (uint16_t)((cpival & 0x1F) * PMW3320_CPI_STEP); } -void pmw3320_set_cpi(uint16_t cpi) { +void pmw3320_set_cpi(const void* config, uint16_t cpi) { + pointing_device_3wire_spi_config_t* pmw3320_config = (pointing_device_3wire_spi_config_t*)config; + uint8_t cpival = constrain((cpi / PMW3320_CPI_STEP) - 1U, 0, (PMW3320_CPI_MAX / PMW3320_CPI_STEP) - 1U); // Fifth bit is probably a control bit. // PMW3320 datasheet don't have any info on this, so this is a pure guess. - pmw3320_write_reg(REG_Resolution, 0x20 | cpival); + pmw3320_write_reg(pmw3320_config, PMW3320_REG_Resolution, 0x20 | cpival); } -bool pmw3320_check_signature(void) { - uint8_t pid = pmw3320_read_reg(REG_Product_ID); - uint8_t pid2 = pmw3320_read_reg(REG_Inverse_Product_ID); +bool pmw3320_check_signature(pointing_device_3wire_spi_config_t* pmw3320_config) { + uint8_t pid = pmw3320_read_reg(pmw3320_config, PMW3320_REG_Product_ID); + uint8_t pid2 = pmw3320_read_reg(pmw3320_config, PMW3320_REG_Inverse_Product_ID); return (pid == 0x3b && pid2 == 0xc4); } + +report_mouse_t pmw3320_get_report(const void* config) { + pointing_device_3wire_spi_config_t* pmw3320_config = (pointing_device_3wire_spi_config_t*)config; + report_pmw3320_t data = pmw3320_read_burst(pmw3320_config); + report_mouse_t mouse_report = {0}; + + if (data.dx != 0 || data.dy != 0) { + pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy); + mouse_report.x = (mouse_xy_report_t)data.dx; + mouse_report.y = (mouse_xy_report_t)data.dy; + } + + return mouse_report; +} \ No newline at end of file diff --git a/drivers/sensors/pmw3320.h b/drivers/sensors/pmw3320.h index a1fd5469196a..9a6a6baf942d 100644 --- a/drivers/sensors/pmw3320.h +++ b/drivers/sensors/pmw3320.h @@ -21,54 +21,31 @@ #include #include +#include "pointing_device.h" #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) -// Definitions for the PMW3320 serial line. -#ifndef PMW3320_SCLK_PIN -# ifdef POINTING_DEVICE_SCLK_PIN -# define PMW3320_SCLK_PIN POINTING_DEVICE_SCLK_PIN -# else -# error "No clock pin defined -- missing POINTING_DEVICE_SCLK_PIN or PMW3320_SCLK_PIN" -# endif -#endif - -#ifndef PMW3320_SDIO_PIN -# ifdef POINTING_DEVICE_SDIO_PIN -# define PMW3320_SDIO_PIN POINTING_DEVICE_SDIO_PIN -# else -# error "No data pin defined -- missing POINTING_DEVICE_SDIO_PIN or PMW3320_SDIO_PIN" -# endif -#endif - -#ifndef PMW3320_CS_PIN -# ifdef POINTING_DEVICE_CS_PIN -# define PMW3320_CS_PIN POINTING_DEVICE_CS_PIN -# else -# error "No chip select pin defined -- missing POINTING_DEVICE_CS_PIN or PMW3320_CS_PIN define" -# endif -#endif - typedef struct { int8_t dx; int8_t dy; } report_pmw3320_t; +const pointing_device_driver_t pmw3320_driver_default; + +#if defined(PMW3320_SCLK_PIN) & defined(PMW3320_SDIO_PIN) & defined(PMW3320_CS_PIN) +const pointing_device_3wire_spi_config_t pmw3320_config_default; +#endif + // A bunch of functions to implement the PMW3320-specific serial protocol. // Mostly taken from ADNS5050 driver. // Note that the "serial.h" driver is insufficient, because it does not // manually manipulate a serial clock signal. -void pmw3320_init(void); -void pmw3320_sync(void); -uint8_t pmw3320_serial_read(void); -void pmw3320_serial_write(uint8_t data); -uint8_t pmw3320_read_reg(uint8_t reg_addr); -void pmw3320_write_reg(uint8_t reg_addr, uint8_t data); -report_pmw3320_t pmw3320_read_burst(void); -void pmw3320_set_cpi(uint16_t cpi); -uint16_t pmw3320_get_cpi(void); -int8_t convert_twoscomp(uint8_t data); -bool pmw3320_check_signature(void); +void pmw3320_init(const void* config); +int8_t paw3320_convert_twoscomp(uint8_t data); +bool pmw3320_check_signature(pointing_device_3wire_spi_config_t* pmw3320_config); +void pmw3320_set_cpi(const void* config, uint16_t cpi); +uint16_t pmw3320_get_cpi(const void* config); +report_mouse_t pmw3320_get_report(const void* config); #if !defined(PMW3320_CPI) # define PMW3320_CPI 1000 @@ -76,44 +53,4 @@ bool pmw3320_check_signature(void); #define PMW3320_CPI_STEP 250 #define PMW3320_CPI_MIN 250 -#define PMW3320_CPI_MAX 3500 - -// PMW3320 register addresses -// clang-format off -#define REG_Product_ID 0x00 -#define REG_Revision_ID 0x01 -#define REG_Motion 0x02 -#define REG_Delta_X 0x03 -#define REG_Delta_Y 0x04 -#define REG_SQUAL 0x05 -#define REG_Shutter_Upper 0x06 -#define REG_Shutter_Lower 0x07 -#define REG_Maximum_Pixel 0x08 -#define REG_Pixel_Accum 0x09 -#define REG_Minimum_Pixel 0x0a -#define REG_Pixel_Grab 0x0b -#define REG_Delta_XY 0x0c -#define REG_Resolution 0x0d -#define REG_Run_Downshift 0x0e -#define REG_Rest1_Period 0x0f -#define REG_Rest1_Downshift 0x10 -#define REG_Rest2_Preiod 0x11 -#define REG_Rest2_Downshift 0x12 -#define REG_Rest3_Period 0x13 -#define REG_Min_SQ_Run 0x17 -#define REG_Axis_Control 0x1a -#define REG_Performance 0x22 -#define REG_Low_Motion_Jitter 0x23 -#define REG_Shutter_Max_HI 0x36 -#define REG_Shutter_Max_LO 0x37 -#define REG_Frame_Rate 0x39 -#define REG_Power_Up_Reset 0x3a -#define REG_Shutdown 0x3b -#define REG_Inverse_Revision_ID 0x3f -#define REG_Led_Control 0x40 -#define REG_Motion_Control 0x41 -#define REG_Burst_Read_First 0x42 -#define REG_Rest_Mode_Status 0x45 -#define REG_Inverse_Product_ID 0x4f -#define REG_Motion_Burst 0x63 -// clang-format on +#define PMW3320_CPI_MAX 3500 \ No newline at end of file diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c index 2e9150b0d259..7a8b56094f4f 100644 --- a/quantum/pointing_device/pointing_device.c +++ b/quantum/pointing_device/pointing_device.c @@ -71,6 +71,32 @@ bool pointing_device_check_shared_cpi_update_flags(void) { return false; } +bool pointing_device_task_handle_shared_report(report_mouse_t* local_report, bool* device_was_ready) { + static uint8_t counter = 0; + if (is_keyboard_master()) { + if (counter != shared_report.counter) { +#if defined(POINTING_DEVICE_DEBUG) + if (shared_report.counter != (((uint16_t)counter + 1) & UINT8_MAX)) { + pd_dprintf("POINTING DEVICE: Missed shared report - last report: %d, new report: %d\n", counter, shared_report.counter); + } +#endif + pointing_device_add_and_clamp_report(local_report, &shared_report.report); + counter = shared_report.counter; + *device_was_ready = true; + return true; + } + } else { + if (*device_was_ready) { + if (pointing_device_report_ready(&shared_report.report, local_report, device_was_ready)) { + memcpy(&shared_report, local_report, sizeof(report_mouse_t)); + shared_report.counter = counter; + counter = (((uint16_t)counter + 1) & UINT8_MAX); + return true; + } + } + } + return false; +} #endif /** @@ -105,15 +131,31 @@ static inline mouse_xy_report_t pointing_device_xy_clamp(clamp_range_t value) { } } -__attribute__((weak)) void pointing_device_init_kb(void) {} +__attribute__((weak)) void pointing_device_init_kb(void) { + pointing_device_init_user(); +} __attribute__((weak)) void pointing_device_init_user(void) {} -__attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report, uint8_t index) { - return pointing_device_task_user(mouse_report, index); +__attribute__((weak)) void pointing_device_init_kb_by_index(uint8_t index) { + pointing_device_init_user_by_index(index); +} + +__attribute__((weak)) void pointing_device_init_user_by_index(uint8_t index) {} + +__attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { + return pointing_device_task_user(mouse_report); +} + +__attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { + return mouse_report; +} + +__attribute__((weak)) report_mouse_t pointing_device_task_kb_by_index(report_mouse_t mouse_report, uint8_t index) { + return pointing_device_task_user_by_index(mouse_report, index); } -__attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report, uint8_t index) { +__attribute__((weak)) report_mouse_t pointing_device_task_user_by_index(report_mouse_t mouse_report, uint8_t index) { return mouse_report; } @@ -147,9 +189,9 @@ __attribute__((weak)) void pointing_device_init(void) { if (pointing_device_configs[i].motion.pin) { setPinInput(pointing_device_configs[i].motion.pin); } + pointing_device_init_kb_by_index(i); } pointing_device_init_kb(); - pointing_device_init_user(); } __attribute__((weak)) void pointing_device_send(report_mouse_t* sending_report) { @@ -228,7 +270,7 @@ bool pointing_deivce_task_get_pointing_reports(report_mouse_t* report) { device_was_ready = true; loop_report = pointing_device_configs[i].driver->get_report(pointing_device_configs[i].config); pointing_device_adjust_report(&loop_report, i); - loop_report = pointing_device_task_kb(loop_report, i); // Maybe simpler to not pass pointer to user? + loop_report = pointing_device_task_kb_by_index(loop_report, i); // Maybe simpler to not pass pointer to user? buttons[i] = loop_report.buttons; pointing_device_add_and_clamp_report(report, &loop_report); } else { @@ -241,48 +283,20 @@ bool pointing_deivce_task_get_pointing_reports(report_mouse_t* report) { return device_was_ready; } -bool pointing_device_task_handle_shared_report(report_mouse_t* local_report, bool* device_was_ready) { - static uint8_t counter = 0; - if (is_keyboard_master()) { - if (counter != shared_report.counter) { -#if defined(POINTING_DEVICE_DEBUG) - if (shared_report.counter != (((uint16_t)counter + 1) & UINT8_MAX)) { - pd_dprintf("POINTING DEVICE: Missed shared report - last report: %d, new report: %d\n", counter, shared_report.counter); - } -#endif - pointing_device_add_and_clamp_report(local_report, &shared_report.report); - counter = shared_report.counter; - *device_was_ready = true; - return true; - } - } else { - if (*device_was_ready) { - if (pointing_device_report_ready(&shared_report.report, local_report, device_was_ready)) { - memcpy(&shared_report, local_report, sizeof(report_mouse_t)); - shared_report.counter = counter; - counter = (((uint16_t)counter + 1) & UINT8_MAX); - return true; - } - } - } - return false; -} - __attribute__((weak)) bool pointing_device_task(void) { bool device_was_ready = pointing_deivce_task_get_pointing_reports(&local_report); bool report_is_different = false; #if defined(SPLIT_KEYBOARD) report_is_different = pointing_device_task_handle_shared_report(&local_report, &device_was_ready); #endif - if (is_keyboard_master()) { + + local_report = pointing_device_task_kb(local_report); + // automatic mouse layer function #ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE pointing_device_task_auto_mouse(local_report); #endif - } -#ifdef POINTING_DEVICE_MODES_ENABLE - local_report = pointing_device_modes_task(local_report); -#endif + // combine with mouse report to ensure that the combined is sent correctly #ifdef MOUSEKEY_ENABLE @@ -295,12 +309,10 @@ __attribute__((weak)) bool pointing_device_task(void) { report_is_different = pointing_device_report_ready(&last_sent_report, &local_report, &device_was_ready); } if (report_is_different) { - memcpy(&last_sent_report, &local_report, sizeof(report_mouse_t)); pointing_device_send(&local_report); } - return report_is_different; } diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h index 9ca2de62e893..f6234a365828 100644 --- a/quantum/pointing_device/pointing_device.h +++ b/quantum/pointing_device/pointing_device.h @@ -77,23 +77,6 @@ typedef struct { uint16_t (*get_cpi)(const void *); } pointing_device_driver_t; -typedef struct { - const pointing_device_driver_t *driver; - const pointing_device_rotations_t rotation; - const pointing_device_invert_t invert; - const uint8_t throttle; - const void *config; - const pointing_device_motion_t motion; -#if defined(SPLIT_KEYBOARD) - const pointing_device_side_t side; -#endif -} pointing_device_config_t; - -typedef struct { - uint16_t cpi; - bool update; -} pointing_device_shared_cpi_t; - typedef enum { POINTING_DEVICE_BUTTON1, POINTING_DEVICE_BUTTON2, @@ -159,6 +142,13 @@ typedef int16_t clamp_range_t; #define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt))) #define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt))) +#define POINTING_DEVICE_NO_MOTION_PIN \ + { 0 } +#define POINTING_DEVICE_THIS_SIDE(index) (pointing_device_configs[index].side == (is_keyboard_left() ? LEFT : RIGHT)) + +#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt))) +#define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt))) + void pointing_device_init(void); bool pointing_device_task(void); void pointing_device_send(report_mouse_t *sending_report); @@ -170,14 +160,40 @@ void pointing_device_set_cpi(uint16_t cpi); uint16_t pointing_device_get_cpi_by_index(uint8_t index); void pointing_device_set_cpi_by_index(uint16_t cpi, uint8_t index); +uint16_t pointing_device_get_cpi_by_index(uint8_t index); +void pointing_device_set_cpi_by_index(uint16_t cpi, uint8_t index); + + +void pointing_device_init_kb_by_index(uint8_t index); +void pointing_device_init_user_by_index(uint8_t index); void pointing_device_init_kb(void); void pointing_device_init_user(void); -report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report, uint8_t index); -report_mouse_t pointing_device_task_user(report_mouse_t mouse_report, uint8_t index); +report_mouse_t pointing_device_task_kb_by_index(report_mouse_t mouse_report, uint8_t index); +report_mouse_t pointing_device_task_user_by_index(report_mouse_t mouse_report, uint8_t index); +report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report); +report_mouse_t pointing_device_task_user(report_mouse_t mouse_report); uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button); void pointing_device_adjust_by_defines(report_mouse_t *report); void pointing_device_keycode_handler(uint16_t keycode, bool pressed); bool pointing_deivce_task_get_pointing_reports(report_mouse_t *report); +bool pointing_deivce_task_get_pointing_reports(report_mouse_t *report); +void pointing_device_add_and_clamp_report(report_mouse_t* report, report_mouse_t* additional_report); +bool pointing_device_report_ready(report_mouse_t* last_report, report_mouse_t* new_report, bool* device_was_ready); + +#if defined(SPLIT_POINTING_ENABLE) +void pointing_device_set_shared_report(report_mouse_t report); +uint16_t pointing_device_get_shared_cpi(void); +# if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) +# define POINTING_DEVICE_TASK_THROTTLE_MS 1 +# endif +# if defined(POINTING_DEVICE_COMBINED) +void pointing_device_set_cpi_on_side(bool left, uint16_t cpi); +report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report); +report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report); +report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report); +report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report); +# endif // defined(POINTING_DEVICE_COMBINED) +#endif // defined(SPLIT_POINTING_ENABLE) void pointing_device_set_shared_report(pointing_device_shared_report_t report); pointing_device_shared_report_t pointing_device_get_shared_report(void);