From 3c58f989295e17d03b66db9a154e02cde7336ece Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Thu, 14 Jul 2022 11:50:00 +0200 Subject: [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 --- drivers/sensors/pmw33xx_common.h | 145 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 drivers/sensors/pmw33xx_common.h (limited to 'drivers/sensors/pmw33xx_common.h') 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) +// Copyright 2019 Sunjun Kim +// Copyright 2020 Ploopy Corporation +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#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); -- cgit v1.2.3 From 580bcff4f65a3a9ee301de0fd036de7b610c7ee2 Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Sat, 16 Jul 2022 11:33:18 +0200 Subject: Use correct angle tune range of +/-30 on PMW33XX (#17693) Co-authored-by: Daniel Kao Co-authored-by: Daniel Kao --- drivers/sensors/pmw33xx_common.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/sensors/pmw33xx_common.h') diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h index 181bea3d43..eab8518baa 100644 --- a/drivers/sensors/pmw33xx_common.h +++ b/drivers/sensors/pmw33xx_common.h @@ -1,3 +1,4 @@ +// Copyright 2022 Daniel Kao (dkao) // Copyright 2022 Stefan Kerkmann (KarlK90) // Copyright 2022 Ulrich Spörlein (@uqs) // Copyright 2021 Alabastard (@Alabastard-64) @@ -58,6 +59,10 @@ _Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.moti # define ROTATIONAL_TRANSFORM_ANGLE 0x00 #endif +#if ROTATIONAL_TRANSFORM_ANGLE > 30 || ROTATIONAL_TRANSFORM_ANGLE < (-30) +# error ROTATIONAL_TRANSFORM_ANGLE has to be in the range of +/- 30 for all PMW33XX sensors. +#endif + // Support single and plural spellings #ifndef PMW33XX_CS_PINS # ifndef PMW33XX_CS_PIN -- cgit v1.2.3 From a304a9b51ed6e876f25c579f383e2cbf9afb8353 Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Sun, 17 Jul 2022 21:08:55 +0200 Subject: Use correct angle tune range of +/-127 on PMW33XX (#17708) ...partially reverts 580bcff4f65a3a9ee301de0fd036de7b610c7ee2 as the datasheet doesn't claim that the angle tuning as limited to +/- 30 degrees. --- drivers/sensors/pmw33xx_common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/sensors/pmw33xx_common.h') diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h index eab8518baa..87e8b34d5c 100644 --- a/drivers/sensors/pmw33xx_common.h +++ b/drivers/sensors/pmw33xx_common.h @@ -59,8 +59,8 @@ _Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.moti # define ROTATIONAL_TRANSFORM_ANGLE 0x00 #endif -#if ROTATIONAL_TRANSFORM_ANGLE > 30 || ROTATIONAL_TRANSFORM_ANGLE < (-30) -# error ROTATIONAL_TRANSFORM_ANGLE has to be in the range of +/- 30 for all PMW33XX sensors. +#if ROTATIONAL_TRANSFORM_ANGLE > 127 || ROTATIONAL_TRANSFORM_ANGLE < (-127) +# error ROTATIONAL_TRANSFORM_ANGLE has to be in the range of +/- 127 for all PMW33XX sensors. #endif // Support single and plural spellings -- cgit v1.2.3 From ccdba43e59fc42c9a91373c65eaa4a026539dc80 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Fri, 12 Aug 2022 16:22:34 -0700 Subject: Create generic Pointing Device Pin defines (#17776) --- drivers/sensors/pmw33xx_common.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/sensors/pmw33xx_common.h') diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h index 87e8b34d5c..c725e80f24 100644 --- a/drivers/sensors/pmw33xx_common.h +++ b/drivers/sensors/pmw33xx_common.h @@ -66,7 +66,13 @@ _Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.moti // 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" +# ifdef POINTING_DEVICE_CS_PIN +# define PMW33XX_CS_PIN POINTING_DEVICE_CS_PIN +# define PMW33XX_CS_PINS \ + { PMW33XX_CS_PIN } +# else +# error "No chip select pin defined -- missing PMW33XX_CS_PIN or PMW33XX_CS_PINS" +# endif # else # define PMW33XX_CS_PINS \ { PMW33XX_CS_PIN } -- cgit v1.2.3