pmw33xx_common.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2022 Daniel Kao (dkao)
  2. // Copyright 2022 Stefan Kerkmann (KarlK90)
  3. // Copyright 2022 Ulrich Spörlein (@uqs)
  4. // Copyright 2021 Alabastard (@Alabastard-64)
  5. // Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
  6. // Copyright 2019 Sunjun Kim
  7. // Copyright 2020 Ploopy Corporation
  8. // SPDX-License-Identifier: GPL-2.0-or-later
  9. #pragma once
  10. #include <stdint.h>
  11. #include "spi_master.h"
  12. #include "util.h"
  13. #if defined(POINTING_DEVICE_DRIVER_pmw3360)
  14. # include "pmw3360.h"
  15. #elif defined(POINTING_DEVICE_DRIVER_pmw3389)
  16. # include "pmw3389.h"
  17. #endif
  18. typedef struct __attribute__((packed)) {
  19. union {
  20. struct {
  21. bool capture_from_raw_data : 1; // FRAME_RData_1st
  22. uint8_t operation_mode : 2; // OP_MODE
  23. bool is_lifted : 1; // Lift_stat
  24. bool raw_data_grab_is_raw_data : 1; // RData_1st
  25. uint8_t _reserved : 2; // 1 + Reserved
  26. bool is_motion : 1; // MOT
  27. } b;
  28. uint8_t w;
  29. } motion;
  30. uint8_t observation;
  31. int16_t delta_x; // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
  32. int16_t delta_y; // displacement on y directions.
  33. } pmw33xx_report_t;
  34. _Static_assert(sizeof(pmw33xx_report_t) == 6, "pmw33xx_report_t must be 6 bytes in size");
  35. _Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.motion must be 1 byte in size");
  36. #if !defined(PMW33XX_CLOCK_SPEED)
  37. # define PMW33XX_CLOCK_SPEED 2000000
  38. #endif
  39. #if !defined(PMW33XX_SPI_DIVISOR)
  40. # ifdef __AVR__
  41. # define PMW33XX_SPI_DIVISOR (F_CPU / PMW33XX_CLOCK_SPEED)
  42. # else
  43. # define PMW33XX_SPI_DIVISOR 64
  44. # endif
  45. #endif
  46. #if !defined(PMW33XX_LIFTOFF_DISTANCE)
  47. # define PMW33XX_LIFTOFF_DISTANCE 0x02
  48. #endif
  49. #if !defined(ROTATIONAL_TRANSFORM_ANGLE)
  50. # define ROTATIONAL_TRANSFORM_ANGLE 0x00
  51. #endif
  52. #if ROTATIONAL_TRANSFORM_ANGLE > 127 || ROTATIONAL_TRANSFORM_ANGLE < (-127)
  53. # error ROTATIONAL_TRANSFORM_ANGLE has to be in the range of +/- 127 for all PMW33XX sensors.
  54. #endif
  55. // Support single and plural spellings
  56. #ifndef PMW33XX_CS_PINS
  57. # ifndef PMW33XX_CS_PIN
  58. # ifdef POINTING_DEVICE_CS_PIN
  59. # define PMW33XX_CS_PIN POINTING_DEVICE_CS_PIN
  60. # define PMW33XX_CS_PINS \
  61. { PMW33XX_CS_PIN }
  62. # else
  63. # error "No chip select pin defined -- missing PMW33XX_CS_PIN or PMW33XX_CS_PINS"
  64. # endif
  65. # else
  66. # define PMW33XX_CS_PINS \
  67. { PMW33XX_CS_PIN }
  68. # endif
  69. #endif
  70. #if PMW33XX_CPI > PMW33XX_CPI_MAX || PMW33XX_CPI < PMW33XX_CPI_MIN || (PMW33XX_CPI % PMW33XX_CPI_STEP) != 0U
  71. # 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) "."
  72. # error Use correct PMW33XX_CPI value.
  73. #endif
  74. #define CONSTRAIN(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
  75. /**
  76. * @brief Initializes the given sensor so it is in a working state and ready to
  77. * be polled for data.
  78. *
  79. * @param sensor Index of the sensors chip select pin
  80. * @return true Initialization was a success
  81. * @return false Initialization failed, do not proceed operation
  82. */
  83. bool __attribute__((cold)) pmw33xx_init(uint8_t sensor);
  84. /**
  85. * @brief Gets the currently set CPI value from the sensor. CPI is often
  86. * refereed to as the sensors sensitivity.
  87. *
  88. * @param sensor Index of the sensors chip select pin
  89. * @return uint16_t Current CPI value of the sensor
  90. */
  91. uint16_t pmw33xx_get_cpi(uint8_t sensor);
  92. /**
  93. * @brief Sets the given CPI value for the given PMW33XX sensor. CIP is often
  94. * refereed to as the sensors sensitivity. Values outside of the allow range are
  95. * constrained into legal values.
  96. *
  97. * @param sensor Index of the sensors chip select pin
  98. * @param cpi CPI value to set, legal range depends on the PMW sensor type
  99. */
  100. void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi);
  101. /**
  102. * @brief Sets the given CPI value to all registered PMW33XX sensors. CPI is
  103. * often refereed to as the sensors sensitivity. Values outside of the allow
  104. * range are constrained into legal values.
  105. *
  106. * @param sensor Index of the sensors chip select pin
  107. * @param cpi CPI value to set, legal range depends on the PMW sensor type
  108. */
  109. void pmw33xx_set_cpi_all_sensors(uint16_t cpi);
  110. /**
  111. * @brief Reads and clears the current delta, and motion register values on the
  112. * given sensor.
  113. *
  114. * @param sensor Index of the sensors chip select pin
  115. * @return pmw33xx_report_t Current values of the sensor, if errors occurred all
  116. * fields are set to zero
  117. */
  118. pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor);
  119. /**
  120. * @brief Read one byte of data from the given register on the sensor
  121. *
  122. * @param sensor Index of the sensors chip select pin
  123. * @param reg_addr Register address to read from
  124. * @return uint8_t
  125. */
  126. uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr);
  127. /**
  128. * @brief Writes one byte of data to the given register on the sensor
  129. *
  130. * @param sensor Index of the sensors chip select pin
  131. * @param reg_addr Registers address to write to
  132. * @param data Data to write to the register
  133. * @return true Write was a success
  134. * @return false Write failed, do not proceed operation
  135. */
  136. bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data);