summaryrefslogtreecommitdiffstats
path: root/drivers/sensors/pmw33xx_common.h
diff options
context:
space:
mode:
authorStefan Kerkmann <karlk90@pm.me>2022-07-14 11:50:00 +0200
committerGitHub <noreply@github.com>2022-07-14 11:50:00 +0200
commit3c58f989295e17d03b66db9a154e02cde7336ece (patch)
treef1e205d8cdc2d28d750bf0545261e9f5cbe609a2 /drivers/sensors/pmw33xx_common.h
parent82685fc2acb0055b56fd57e9a842412a3e3a246c (diff)
[Core] PMW33XX drivers overhaul (#17613)
* PMW33XX drivers overhaul This combines the PMW3389 and PM3360 drivers as they only differ in the firmware blobs and CPI get and set functions. The following changes have been made: * PMW3389 now gets the same multi-sensor feature that is already available on the PMW3360. * Introduced a shared pmw33xx_report_t struct is now directly readable via SPI transactions instead of individual byte-sized reads, saving multiple copies and bitshift operations. * pmw33(89/60)_get_report functions had unreachable branches in their motion detection logic these have been simplied as much as possible. * The fast firmware upload option has been removed as this becomes obsolete by the newly introduced polled waiting functions for ChibiOS polled waiting * PMW33(60/89)_SPI_LSBFIRST and PMW33(60/89)_SPI_MODE config options have been removed as they don't need to be configurable. * All PMW3389 and PMW3360 defines have been unified to a PMW33XX prefix to reduce code duplication and make the defines interchangeable * Adjust keyboards to PMW33XX naming scheme
Diffstat (limited to 'drivers/sensors/pmw33xx_common.h')
-rw-r--r--drivers/sensors/pmw33xx_common.h145
1 files changed, 145 insertions, 0 deletions
diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h
new file mode 100644
index 0000000000..181bea3d43
--- /dev/null
+++ b/drivers/sensors/pmw33xx_common.h
@@ -0,0 +1,145 @@
+// Copyright 2022 Stefan Kerkmann (KarlK90)
+// Copyright 2022 Ulrich Spörlein (@uqs)
+// Copyright 2021 Alabastard (@Alabastard-64)
+// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+// Copyright 2019 Sunjun Kim
+// Copyright 2020 Ploopy Corporation
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+#include "spi_master.h"
+#include "util.h"
+
+#if defined(POINTING_DEVICE_DRIVER_pmw3360)
+# include "pmw3360.h"
+#elif defined(POINTING_DEVICE_DRIVER_pmw3389)
+# include "pmw3389.h"
+#endif
+
+typedef struct __attribute__((packed)) {
+ union {
+ struct {
+ bool capture_from_raw_data : 1; // FRAME_RData_1st
+ uint8_t operation_mode : 2; // OP_MODE
+ bool is_lifted : 1; // Lift_stat
+ bool raw_data_grab_is_raw_data : 1; // RData_1st
+ uint8_t _reserved : 2; // 1 + Reserved
+ bool is_motion : 1; // MOT
+ } b;
+ uint8_t w;
+ } motion;
+ uint8_t observation;
+ int16_t delta_x; // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
+ int16_t delta_y; // displacement on y directions.
+} pmw33xx_report_t;
+
+_Static_assert(sizeof(pmw33xx_report_t) == 6, "pmw33xx_report_t must be 6 bytes in size");
+_Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.motion must be 1 byte in size");
+
+#if !defined(PMW33XX_CLOCK_SPEED)
+# define PMW33XX_CLOCK_SPEED 2000000
+#endif
+
+#if !defined(PMW33XX_SPI_DIVISOR)
+# ifdef __AVR__
+# define PMW33XX_SPI_DIVISOR (F_CPU / PMW33XX_CLOCK_SPEED)
+# else
+# define PMW33XX_SPI_DIVISOR 64
+# endif
+#endif
+
+#if !defined(PMW33XX_LIFTOFF_DISTANCE)
+# define PMW33XX_LIFTOFF_DISTANCE 0x02
+#endif
+
+#if !defined(ROTATIONAL_TRANSFORM_ANGLE)
+# define ROTATIONAL_TRANSFORM_ANGLE 0x00
+#endif
+
+// Support single and plural spellings
+#ifndef PMW33XX_CS_PINS
+# ifndef PMW33XX_CS_PIN
+# error "No chip select pin defined -- missing PMW33XX_CS_PIN or PMW33XX_CS_PINS"
+# else
+# define PMW33XX_CS_PINS \
+ { PMW33XX_CS_PIN }
+# endif
+#endif
+
+#if PMW33XX_CPI > PMW33XX_CPI_MAX || PMW33XX_CPI < PMW33XX_CPI_MIN || (PMW33XX_CPI % PMW33XX_CPI_STEP) != 0U
+# 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) "."
+# error Use correct PMW33XX_CPI value.
+#endif
+
+#define CONSTRAIN(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
+
+/**
+ * @brief Initializes the given sensor so it is in a working state and ready to
+ * be polled for data.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @return true Initialization was a success
+ * @return false Initialization failed, do not proceed operation
+ */
+bool __attribute__((cold)) pmw33xx_init(uint8_t sensor);
+
+/**
+ * @brief Gets the currently set CPI value from the sensor. CPI is often
+ * refereed to as the sensors sensitivity.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @return uint16_t Current CPI value of the sensor
+ */
+uint16_t pmw33xx_get_cpi(uint8_t sensor);
+
+/**
+ * @brief Sets the given CPI value for the given PMW33XX sensor. CIP is often
+ * refereed to as the sensors sensitivity. Values outside of the allow range are
+ * constrained into legal values.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param cpi CPI value to set, legal range depends on the PMW sensor type
+ */
+void pmw33xx_set_cpi(uint8_t sensor, uint16_t cpi);
+
+/**
+ * @brief Sets the given CPI value to all registered PMW33XX sensors. CPI is
+ * often refereed to as the sensors sensitivity. Values outside of the allow
+ * range are constrained into legal values.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param cpi CPI value to set, legal range depends on the PMW sensor type
+ */
+void pmw33xx_set_cpi_all_sensors(uint16_t cpi);
+
+/**
+ * @brief Reads and clears the current delta, and motion register values on the
+ * given sensor.
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @return pmw33xx_report_t Current values of the sensor, if errors occurred all
+ * fields are set to zero
+ */
+pmw33xx_report_t pmw33xx_read_burst(uint8_t sensor);
+
+/**
+ * @brief Read one byte of data from the given register on the sensor
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param reg_addr Register address to read from
+ * @return uint8_t
+ */
+uint8_t pmw33xx_read(uint8_t sensor, uint8_t reg_addr);
+
+/**
+ * @brief Writes one byte of data to the given register on the sensor
+ *
+ * @param sensor Index of the sensors chip select pin
+ * @param reg_addr Registers address to write to
+ * @param data Data to write to the register
+ * @return true Write was a success
+ * @return false Write failed, do not proceed operation
+ */
+bool pmw33xx_write(uint8_t sensor, uint8_t reg_addr, uint8_t data);