pmw33xx_common.h (6541B)
1 // Copyright 2022 Pablo Martinez (@elpekenin) 2 // Copyright 2022 Daniel Kao (dkao) 3 // Copyright 2022 Stefan Kerkmann (KarlK90) 4 // Copyright 2022 Ulrich Spörlein (@uqs) 5 // Copyright 2021 Alabastard (@Alabastard-64) 6 // Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> 7 // Copyright 2019 Sunjun Kim 8 // Copyright 2020 Ploopy Corporation 9 // SPDX-License-Identifier: GPL-2.0-or-later 10 11 #pragma once 12 13 #include "compiler_support.h" 14 #include "keyboard.h" 15 #include <stdint.h> 16 #include "spi_master.h" 17 #include "util.h" 18 #include "pointing_device.h" 19 20 #if defined(POINTING_DEVICE_DRIVER_pmw3360) 21 # include "pmw3360.h" 22 #elif defined(POINTING_DEVICE_DRIVER_pmw3389) 23 # include "pmw3389.h" 24 #endif 25 26 typedef struct __attribute__((packed)) { 27 union { 28 struct { 29 bool capture_from_raw_data : 1; // FRAME_RData_1st 30 uint8_t operation_mode : 2; // OP_MODE 31 bool is_lifted : 1; // Lift_stat 32 bool raw_data_grab_is_raw_data : 1; // RData_1st 33 uint8_t _reserved : 2; // 1 + Reserved 34 bool is_motion : 1; // MOT 35 } b; 36 uint8_t w; 37 } motion; 38 uint8_t observation; 39 int16_t delta_x; // displacement on x directions. Unit: Count. (CPI * Count = Inch value) 40 int16_t delta_y; // displacement on y directions. 41 } pmw33xx_report_t; 42 43 STATIC_ASSERT(sizeof(pmw33xx_report_t) == 6, "pmw33xx_report_t must be 6 bytes in size"); 44 STATIC_ASSERT(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.motion must be 1 byte in size"); 45 46 #if !defined(PMW33XX_CLOCK_SPEED) 47 # define PMW33XX_CLOCK_SPEED 2000000 48 #endif 49 50 #if !defined(PMW33XX_SPI_DIVISOR) 51 # ifdef __AVR__ 52 # define PMW33XX_SPI_DIVISOR (F_CPU / PMW33XX_CLOCK_SPEED) 53 # else 54 # define PMW33XX_SPI_DIVISOR 64 55 # endif 56 #endif 57 58 #if !defined(PMW33XX_LIFTOFF_DISTANCE) 59 # define PMW33XX_LIFTOFF_DISTANCE 0x02 60 #endif 61 62 #if !defined(ROTATIONAL_TRANSFORM_ANGLE) 63 # define ROTATIONAL_TRANSFORM_ANGLE 0x00 64 #endif 65 66 #if ROTATIONAL_TRANSFORM_ANGLE > 127 || ROTATIONAL_TRANSFORM_ANGLE < (-127) 67 # error ROTATIONAL_TRANSFORM_ANGLE has to be in the range of +/- 127 for all PMW33XX sensors. 68 #endif 69 70 // Support single and plural spellings 71 #ifndef PMW33XX_CS_PINS 72 # ifndef PMW33XX_CS_PIN 73 # ifdef POINTING_DEVICE_CS_PIN 74 # define PMW33XX_CS_PIN POINTING_DEVICE_CS_PIN 75 # define PMW33XX_CS_PINS {PMW33XX_CS_PIN} 76 # else 77 # error "No chip select pin defined -- missing PMW33XX_CS_PIN or PMW33XX_CS_PINS" 78 # endif 79 # else 80 # define PMW33XX_CS_PINS {PMW33XX_CS_PIN} 81 # endif 82 #endif 83 84 // Support single spelling and default to be the same as left side 85 #if !defined(PMW33XX_CS_PINS_RIGHT) 86 # if !defined(PMW33XX_CS_PIN_RIGHT) 87 # define PMW33XX_CS_PIN_RIGHT PMW33XX_CS_PIN 88 # endif 89 # define PMW33XX_CS_PINS_RIGHT {PMW33XX_CS_PIN_RIGHT} 90 #endif 91 92 // Defines so the old variable names are swapped by the appropiate value on each half 93 #define cs_pins (is_keyboard_left() ? cs_pins_left : cs_pins_right) 94 #define in_burst (is_keyboard_left() ? in_burst_left : in_burst_right) 95 #define pmw33xx_number_of_sensors (is_keyboard_left() ? ARRAY_SIZE((pin_t[])PMW33XX_CS_PINS) : ARRAY_SIZE((pin_t[])PMW33XX_CS_PINS_RIGHT)) 96 97 #if PMW33XX_CPI > PMW33XX_CPI_MAX || PMW33XX_CPI < PMW33XX_CPI_MIN || (PMW33XX_CPI % PMW33XX_CPI_STEP) != 0U 98 # pragma message "PMW33XX_CPI has to be in the range of " STR(PMW33XX_CPI_MAX) "-" STR(PMW33XX_CPI_MIN) " in increments of " STR(PMW33XX_CPI_STEP) ". But it is " STR(PMW33XX_CPI) "." 99 # error Use correct PMW33XX_CPI value. 100 #endif 101 102 #define CONSTRAIN(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) 103 104 #define pmw3360_pointing_device_driver pmw33xx_pointing_device_driver; 105 #define pmw3389_pointing_device_driver pmw33xx_pointing_device_driver; 106 extern const pointing_device_driver_t pmw33xx_pointing_device_driver; 107 108 /** 109 * @brief Initializes the given sensor so it is in a working state and ready to 110 * be polled for data. 111 * 112 * @param sensor Index of the sensors chip select pin 113 * @return true Initialization was a success 114 * @return false Initialization failed, do not proceed operation 115 */ 116 bool __attribute__((cold)) pmw33xx_init(uint8_t sensor); 117 118 /** 119 * @brief Gets the currently set CPI value from the sensor. CPI is often 120 * refereed to as the sensors sensitivity. 121 * 122 * @param sensor Index of the sensors chip select pin 123 * @return uint16_t Current CPI value of the sensor 124 */ 125 uint16_t pmw33xx_get_cpi(uint8_t sensor); 126 127 /** 128 * @brief Sets the given CPI value for the given PMW33XX sensor. CIP is often 129 * refereed to as the sensors sensitivity. Values outside of the allow range are 130 * constrained into legal values. 131 * 132 * @param sensor Index of the sensors chip select pin 133 * @param cpi CPI value to set, legal range depends on the PMW sensor type 134 */ 135 void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi); 136 137 /** 138 * @brief Sets the given CPI value to all registered PMW33XX sensors. CPI is 139 * often refereed to as the sensors sensitivity. Values outside of the allow 140 * range are constrained into legal values. 141 * 142 * @param sensor Index of the sensors chip select pin 143 * @param cpi CPI value to set, legal range depends on the PMW sensor type 144 */ 145 void pmw33xx_set_cpi_all_sensors(uint16_t cpi); 146 147 /** 148 * @brief Reads and clears the current delta, and motion register values on the 149 * given sensor. 150 * 151 * @param sensor Index of the sensors chip select pin 152 * @return pmw33xx_report_t Current values of the sensor, if errors occurred all 153 * fields are set to zero 154 */ 155 pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor); 156 157 /** 158 * @brief Read one byte of data from the given register on the sensor 159 * 160 * @param sensor Index of the sensors chip select pin 161 * @param reg_addr Register address to read from 162 * @return uint8_t 163 */ 164 uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr); 165 166 /** 167 * @brief Writes one byte of data to the given register on the sensor 168 * 169 * @param sensor Index of the sensors chip select pin 170 * @param reg_addr Registers address to write to 171 * @param data Data to write to the register 172 * @return true Write was a success 173 * @return false Write failed, do not proceed operation 174 */ 175 bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data); 176 177 bool pmw33xx_init_wrapper(void); 178 void pmw33xx_set_cpi_wrapper(uint16_t cpi); 179 uint16_t pmw33xx_get_cpi_wrapper(void); 180 report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report);