qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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