From 00072b4fb4abe73b554a0f2f1cefc68dc3bfbc79 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 5 Jul 2022 20:33:29 -0700 Subject: [PATCH 01/10] Add PAW3204 Optical Sensor Co-authored-by: gompa --- docs/feature_pointing_device.md | 25 ++++++ drivers/sensors/paw3204.c | 133 ++++++++++++++++++++++++++++++ drivers/sensors/paw3204.h | 63 ++++++++++++++ quantum/pointing_device.h | 2 + quantum/pointing_device_drivers.c | 21 +++++ 5 files changed, 244 insertions(+) create mode 100644 drivers/sensors/paw3204.c create mode 100644 drivers/sensors/paw3204.h diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index 6343ed073d51..32286d90bb52 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -136,6 +136,31 @@ Also see the `POINTING_DEVICE_TASK_THROTTLE_MS`, which defaults to 10ms when usi **`POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`** is not specific to Cirque trackpad; any pointing device with a lift/contact status can integrate this gesture into its driver. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `pointing_device_get_report()` is needed to generate glide reports. +### PAW 3204 Sensor + +To use the paw 3204 sensor, add this to your `rules.mk` + +```make +POINTING_DEVICE_DRIVER = paw3204 +``` + +The paw 3204 sensor uses a serial type protocol for communication, and requires an additional light source. + +| Setting | Description | +|--------------------|---------------------------------------------------------------------| +|`PAW3204_SCLK` | (Required) The pin connected to the clock pin of the sensor. | +|`PAW3204_SDIO` | (Required) The pin connected to the data pin of the sensor. | + +Output resolution setting +bit: +000 = 400 +001 = 500 +010 = 600 +011 = 800 +100 = 1000 (Default) +101 = 1200 +110 = 1600 + ### Pimoroni Trackball To use the Pimoroni Trackball module, add this to your `rules.mk`: diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c new file mode 100644 index 000000000000..c4c687ebf911 --- /dev/null +++ b/drivers/sensors/paw3204.c @@ -0,0 +1,133 @@ +/* Copyright 2021 Gompa (@Gompa) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "paw3204.h" +#include "wait.h" +#include "debug.h" +#include "gpio.h" + +uint8_t datatogglestate; +#define REG_PID1 0x00 +#define REG_PID2 0x01 +#define REG_STAT 0x02 +#define REG_X 0x03 +#define REG_Y 0x04 + +#define REG_SETUP 0x06 +#define REG_IMGQUAL 0x07 +#define REG_IMGREC 0x0E +#define REG_IMGTRASH 0x0D + +void PAW3204_init(void) { + setPinOutput(PAW3204_SCLK); // setclockpin to output + setPinInputHigh(PAW3204_DATA); // set datapin input high + + PAW3204_write_reg(REG_SETUP, 0x86); // reset sensor and set 1600cpi + wait_us(5); + + PAW3204_read_reg(0x00); // read id + PAW3204_read_reg(0x01); // read id2 + // PAW3204_write_reg(REG_SETUP,0x06); // dont reset sensor and set cpi 1600 + PAW3204_write_reg(REG_IMGTRASH, 0x32); // write image trashhold +} + +uint8_t PAW3204_serial_read(void) { + setPinInput(PAW3204_DATA); + uint8_t byte = 0; + + for (uint8_t i = 0; i < 8; ++i) { + writePinLow(PAW3204_SCLK); + wait_us(1); + + byte = (byte << 1) | readPin(PAW3204_DATA); + + writePinHigh(PAW3204_SCLK); + wait_us(1); + } + + return byte; +} + +void PAW3204_serial_write(uint8_t data) { + datatogglestate = readPin(PAW3204_DATA); + if (datatogglestate == 1) { + writePinLow(PAW3204_DATA); + } else { + writePinLow(PAW3204_DATA); + } + setPinOutput(PAW3204_DATA); + + for (int8_t b = 7; b >= 0; b--) { + writePinLow(PAW3204_SCLK); + if (data & (1 << b)) + writePinHigh(PAW3204_DATA); + else + writePinLow(PAW3204_DATA); + // wait_us(2); + writePinHigh(PAW3204_SCLK); + } + + wait_us(4); +} + +int8_t convert_twoscomp(uint8_t data) { + if ((data & 0x80) == 0x80) + return -128 + (data & 0x7F); + else + return data; +} + +report_paw3204_t PAW3204_read(void) { + report_paw3204_t data; + uint8_t pid = read_pid_paw3204(); + uint8_t stat = PAW3204_read_reg(REG_STAT); + if (pid == 0x30 && (stat == 0x84 || stat == 0x86)) { + data.x = convert_twoscomp(PAW3204_read_reg(REG_X)); + data.y = convert_twoscomp(PAW3204_read_reg(REG_Y)); + } + + return data; +} + +void PAW3204_write_reg(uint8_t reg_addr, uint8_t data) { + PAW3204_serial_write(0b10000000 | reg_addr); + PAW3204_serial_write(data); +} + +uint8_t PAW3204_read_reg(uint8_t reg_addr) { + PAW3204_serial_write(reg_addr); + + wait_us(5); + + uint8_t byte = PAW3204_serial_read(); + + return byte; +} + +void PAW3204_set_cpi(uint16_t cpi) { + uint8_t cpival = constrain((cpi / 200) - 2, 0x0, 0x6); + PAW3204_write_reg(REG_SETUP, cpival); +} + +uint16_t PAW3204_get_cpi(void) { + uint8_t cpival = PAW3204_read_reg(REG_SETUP); + return (uint16_t)(cpival + 2) * 200; +} + +uint8_t read_pid_paw3204(void) { + uint8_t byte = PAW3204_read_reg(REG_PID1); + return byte; +} \ No newline at end of file diff --git a/drivers/sensors/paw3204.h b/drivers/sensors/paw3204.h new file mode 100644 index 000000000000..d9890560370f --- /dev/null +++ b/drivers/sensors/paw3204.h @@ -0,0 +1,63 @@ +/* Copyright 2021 Gompa (@Gompa) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +#ifndef PAW3204_SCLK +# error "No clock pin defined -- missing PAW3204_SCLK" +#endif + +#ifndef PAW3204_DATA +# error "No data pin defined -- missing PAW3204_DATA" +#endif +#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) + +// CPI values +// clang-format off +#define CPI400 0x00 +#define CPI500 0x01 +#define CPI600 0x02 +#define CPI800 0x03 +#define CPI1000 0x04 +#define CPI1200 0x05 +#define CPI1600 0x06 +// clang-format on + +typedef struct { + int8_t x; + int8_t y; +} report_paw3204_t; + +// A bunch of functions to implement the paw3204-specific serial protocol. +// Note that the "serial.h" driver is insufficient, because it does not +// manually manipulate a serial clock signal. + +void PAW3204_init(void); +// void adns5050_sync(void); +report_paw3204_t PAW3204_read(void); +uint8_t PAW3204_serial_read(void); +void PAW3204_serial_write(uint8_t reg_addr); +uint8_t PAW3204_read_reg(uint8_t reg_addr); +void PAW3204_write_reg(uint8_t reg_addr, uint8_t data); +// void PAW3204_set_cpi(uint16_t cpi); +// uint16_t PAW3204_get_cpi(void); +int8_t convert_twoscomp(uint8_t data); +uint8_t read_pid_paw3204(void) ; +void PAW3204_set_cpi(uint16_t cpi); +uint16_t PAW3204_get_cpi(void); + diff --git a/quantum/pointing_device.h b/quantum/pointing_device.h index a8e8e75e8712..77db5471eac6 100644 --- a/quantum/pointing_device.h +++ b/quantum/pointing_device.h @@ -33,6 +33,8 @@ along with this program. If not, see . # include "drivers/sensors/cirque_pinnacle.h" # include "drivers/sensors/cirque_pinnacle_gestures.h" # include "pointing_device_gestures.h" +#elif defined(POINTING_DEVICE_DRIVER_paw3204) +# include "drivers/sensors/paw3204.h" #elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball) # include "i2c_master.h" # include "drivers/sensors/pimoroni_trackball.h" diff --git a/quantum/pointing_device_drivers.c b/quantum/pointing_device_drivers.c index b7e98e897e4f..4be2226534c2 100644 --- a/quantum/pointing_device_drivers.c +++ b/quantum/pointing_device_drivers.c @@ -26,6 +26,7 @@ #define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt))) // get_report functions should probably be moved to their respective drivers. + #if defined(POINTING_DEVICE_DRIVER_adns5050) report_mouse_t adns5050_get_report(report_mouse_t mouse_report) { report_adns5050_t data = adns5050_read_burst(); @@ -198,7 +199,27 @@ const pointing_device_driver_t pointing_device_driver = { .get_cpi = cirque_pinnacle_get_cpi }; // clang-format on +#elif defined(POINTING_DEVICE_DRIVER_paw3204) + +report_mouse_t paw3204_get_report(report_mouse_t mouse_report) { + report_paw3204_t data = PAW3204_read(); + if (data.x != 0 || data.y != 0) { +# ifdef CONSOLE_ENABLE + dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y); +# endif + + mouse_report.x = data.x; + mouse_report.y = data.y; + } + return mouse_report; +} +const pointing_device_driver_t pointing_device_driver = { + .init = PAW3204_init, + .get_report = paw3204_get_report, + .set_cpi = PAW3204_set_cpi, + .get_cpi = PAW3204_get_cpi, +}; #elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball) mouse_xy_report_t pimoroni_trackball_adapt_values(clamp_range_t* offset) { From 4cf45524f98113e42aa5468436954d3458531080 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 5 Jul 2022 21:25:16 -0700 Subject: [PATCH 02/10] Update code --- builddefs/common_features.mk | 2 +- drivers/sensors/paw3204.c | 141 ++++++++++++++++++++---------- drivers/sensors/paw3204.h | 49 ++++------- quantum/pointing_device_drivers.c | 10 +-- 4 files changed, 118 insertions(+), 84 deletions(-) diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index d7a00ba94426..9ee51149ef06 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -126,7 +126,7 @@ ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) SRC += $(QUANTUM_DIR)/mousekey.c endif -VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi pmw3360 pmw3389 pimoroni_trackball custom +VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3360 pmw3389 pimoroni_trackball custom ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),) $(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index c4c687ebf911..cf8b77e52a22 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -31,53 +31,66 @@ uint8_t datatogglestate; #define REG_IMGREC 0x0E #define REG_IMGTRASH 0x0D -void PAW3204_init(void) { - setPinOutput(PAW3204_SCLK); // setclockpin to output - setPinInputHigh(PAW3204_DATA); // set datapin input high - - PAW3204_write_reg(REG_SETUP, 0x86); // reset sensor and set 1600cpi +#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) + +// CPI values +enum cpi_values { + CPI400, // 0b000 + CPI500, // 0b001 + CPI600, // 0b010 + CPI800, // 0b011 + CPI1000, // 0b100 + CPI1200, // 0b101 + CPI1600, // 0b110 +}; + +void paw3204_init(void) { + setPinOutput(PAW3204_SCLK_PIN); // setclockpin to output + setPinInputHigh(PAW3204_SDIO_PIN); // set datapin input high + + paw3204_write_reg(REG_SETUP, 0x86); // reset sensor and set 1600cpi wait_us(5); - PAW3204_read_reg(0x00); // read id - PAW3204_read_reg(0x01); // read id2 + paw3204_read_reg(0x00); // read id + paw3204_read_reg(0x01); // read id2 // PAW3204_write_reg(REG_SETUP,0x06); // dont reset sensor and set cpi 1600 - PAW3204_write_reg(REG_IMGTRASH, 0x32); // write image trashhold + paw3204_write_reg(REG_IMGTRASH, 0x32); // write image trashhold } -uint8_t PAW3204_serial_read(void) { - setPinInput(PAW3204_DATA); +uint8_t paw3204_serial_read(void) { + setPinInput(PAW3204_SDIO_PIN); uint8_t byte = 0; for (uint8_t i = 0; i < 8; ++i) { - writePinLow(PAW3204_SCLK); + writePinLow(PAW3204_SCLK_PIN); wait_us(1); - byte = (byte << 1) | readPin(PAW3204_DATA); + byte = (byte << 1) | readPin(PAW3204_SDIO_PIN); - writePinHigh(PAW3204_SCLK); + writePinHigh(PAW3204_SCLK_PIN); wait_us(1); } return byte; } -void PAW3204_serial_write(uint8_t data) { - datatogglestate = readPin(PAW3204_DATA); +void paw3204_serial_write(uint8_t data) { + datatogglestate = readPin(PAW3204_SDIO_PIN); if (datatogglestate == 1) { - writePinLow(PAW3204_DATA); + writePinLow(PAW3204_SDIO_PIN); } else { - writePinLow(PAW3204_DATA); + writePinLow(PAW3204_SDIO_PIN); } - setPinOutput(PAW3204_DATA); + setPinOutput(PAW3204_SDIO_PIN); for (int8_t b = 7; b >= 0; b--) { - writePinLow(PAW3204_SCLK); + writePinLow(PAW3204_SCLK_PIN); if (data & (1 << b)) - writePinHigh(PAW3204_DATA); + writePinHigh(PAW3204_SDIO_PIN); else - writePinLow(PAW3204_DATA); + writePinLow(PAW3204_SDIO_PIN); // wait_us(2); - writePinHigh(PAW3204_SCLK); + writePinHigh(PAW3204_SCLK_PIN); } wait_us(4); @@ -90,44 +103,80 @@ int8_t convert_twoscomp(uint8_t data) { return data; } -report_paw3204_t PAW3204_read(void) { - report_paw3204_t data; - uint8_t pid = read_pid_paw3204(); - uint8_t stat = PAW3204_read_reg(REG_STAT); - if (pid == 0x30 && (stat == 0x84 || stat == 0x86)) { - data.x = convert_twoscomp(PAW3204_read_reg(REG_X)); - data.y = convert_twoscomp(PAW3204_read_reg(REG_Y)); - } +report_paw3204_t paw3204_read(void) { + report_paw3204_t data = {0}; + + data.isMotion = paw3204_read_reg(REG_STAT) & (1 << 7); // check for motion only (bit 7 in field) + data.x = convert_twoscomp(paw3204_read_reg(REG_X)); + data.y = convert_twoscomp(paw3204_read_reg(REG_Y)); return data; } -void PAW3204_write_reg(uint8_t reg_addr, uint8_t data) { - PAW3204_serial_write(0b10000000 | reg_addr); - PAW3204_serial_write(data); +void paw3204_write_reg(uint8_t reg_addr, uint8_t data) { + paw3204_serial_write(0b10000000 | reg_addr); + paw3204_serial_write(data); } -uint8_t PAW3204_read_reg(uint8_t reg_addr) { - PAW3204_serial_write(reg_addr); +uint8_t paw3204_read_reg(uint8_t reg_addr) { + uint8_t byte = 0; + paw3204_serial_write(reg_addr); wait_us(5); - - uint8_t byte = PAW3204_serial_read(); + byte = paw3204_serial_read(); return byte; } -void PAW3204_set_cpi(uint16_t cpi) { - uint8_t cpival = constrain((cpi / 200) - 2, 0x0, 0x6); - PAW3204_write_reg(REG_SETUP, cpival); +void paw3204_set_cpi(uint16_t cpi) { + uint8_t cpival = CPI1000; + if (cpi <= 450) { + cpival = CPI400; + } else if (cpi <= 550) { + cpival = CPI500; + } else if (cpi <= 700) { + cpival = CPI600; + } else if (cpi <= 900) { + cpival = CPI800; + } else if (cpi <= 1100) { + cpival = CPI1000; + } else if (cpi <= 1400) { + cpival = CPI1200; + } else if (cpi > 1400) { + cpival = CPI1600; + } + paw3204_write_reg(REG_SETUP, cpival); } -uint16_t PAW3204_get_cpi(void) { - uint8_t cpival = PAW3204_read_reg(REG_SETUP); - return (uint16_t)(cpival + 2) * 200; +uint16_t paw3204_get_cpi(void) { + uint16_t cpival = 1000; + + switch (paw3204_read_reg(REG_SETUP) & 0b111) { + case CPI400: + cpival = 400; + break; + case CPI500: + cpival = 500; + break; + case CPI600: + cpival = 600; + break; + case CPI800: + cpival = 800; + break; + case CPI1000: + cpival = 1000; + break; + case CPI1200: + cpival = 1200; + break; + case CPI1600: + cpival = 1600; + break; + } + return cpival; } uint8_t read_pid_paw3204(void) { - uint8_t byte = PAW3204_read_reg(REG_PID1); - return byte; -} \ No newline at end of file + return paw3204_read_reg(REG_PID1); +} diff --git a/drivers/sensors/paw3204.h b/drivers/sensors/paw3204.h index d9890560370f..e766b2f0305f 100644 --- a/drivers/sensors/paw3204.h +++ b/drivers/sensors/paw3204.h @@ -17,47 +17,32 @@ #pragma once #include +#include -#ifndef PAW3204_SCLK -# error "No clock pin defined -- missing PAW3204_SCLK" +#ifndef PAW3204_SCLK_PIN +# error "No clock pin defined -- missing PAW3204_SCLK_PIN" #endif - -#ifndef PAW3204_DATA -# error "No data pin defined -- missing PAW3204_DATA" +#ifndef PAW3204_SDIO_PIN +# error "No data pin defined -- missing PAW3204_SDIO_PIN" #endif -#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) - -// CPI values -// clang-format off -#define CPI400 0x00 -#define CPI500 0x01 -#define CPI600 0x02 -#define CPI800 0x03 -#define CPI1000 0x04 -#define CPI1200 0x05 -#define CPI1600 0x06 -// clang-format on typedef struct { - int8_t x; - int8_t y; + int16_t x; + int16_t y; + bool isMotion; } report_paw3204_t; // A bunch of functions to implement the paw3204-specific serial protocol. // Note that the "serial.h" driver is insufficient, because it does not // manually manipulate a serial clock signal. -void PAW3204_init(void); -// void adns5050_sync(void); -report_paw3204_t PAW3204_read(void); -uint8_t PAW3204_serial_read(void); -void PAW3204_serial_write(uint8_t reg_addr); -uint8_t PAW3204_read_reg(uint8_t reg_addr); -void PAW3204_write_reg(uint8_t reg_addr, uint8_t data); -// void PAW3204_set_cpi(uint16_t cpi); -// uint16_t PAW3204_get_cpi(void); +void paw3204_init(void); +report_paw3204_t paw3204_read(void); +uint8_t paw3204_serial_read(void); +void paw3204_serial_write(uint8_t reg_addr); +uint8_t paw3204_read_reg(uint8_t reg_addr); +void paw3204_write_reg(uint8_t reg_addr, uint8_t data); int8_t convert_twoscomp(uint8_t data); -uint8_t read_pid_paw3204(void) ; -void PAW3204_set_cpi(uint16_t cpi); -uint16_t PAW3204_get_cpi(void); - +uint8_t read_pid_paw3204(void); +void paw3204_set_cpi(uint16_t cpi); +uint16_t paw3204_get_cpi(void); diff --git a/quantum/pointing_device_drivers.c b/quantum/pointing_device_drivers.c index 4be2226534c2..d0b545d22d40 100644 --- a/quantum/pointing_device_drivers.c +++ b/quantum/pointing_device_drivers.c @@ -202,8 +202,8 @@ const pointing_device_driver_t pointing_device_driver = { #elif defined(POINTING_DEVICE_DRIVER_paw3204) report_mouse_t paw3204_get_report(report_mouse_t mouse_report) { - report_paw3204_t data = PAW3204_read(); - if (data.x != 0 || data.y != 0) { + report_paw3204_t data = paw3204_read(); + if (data.isMotion) { # ifdef CONSOLE_ENABLE dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y); # endif @@ -215,10 +215,10 @@ report_mouse_t paw3204_get_report(report_mouse_t mouse_report) { return mouse_report; } const pointing_device_driver_t pointing_device_driver = { - .init = PAW3204_init, + .init = paw3204_init, .get_report = paw3204_get_report, - .set_cpi = PAW3204_set_cpi, - .get_cpi = PAW3204_get_cpi, + .set_cpi = paw3204_set_cpi, + .get_cpi = paw3204_get_cpi, }; #elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball) From 95cc61944590d2896a390267330bffe7a9bb2e77 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 5 Jul 2022 21:39:37 -0700 Subject: [PATCH 03/10] Update docs --- docs/feature_pointing_device.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index 32286d90bb52..f0463a131dd0 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -148,18 +148,11 @@ The paw 3204 sensor uses a serial type protocol for communication, and requires | Setting | Description | |--------------------|---------------------------------------------------------------------| -|`PAW3204_SCLK` | (Required) The pin connected to the clock pin of the sensor. | -|`PAW3204_SDIO` | (Required) The pin connected to the data pin of the sensor. | - -Output resolution setting -bit: -000 = 400 -001 = 500 -010 = 600 -011 = 800 -100 = 1000 (Default) -101 = 1200 -110 = 1600 +|`PAW3204_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | +|`PAW3204_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | + +The CPI range is 400-1600, with supported values of (400, 500, 600, 800, 1000, 1200 and 1600). Defaults to 1000 CPI. + ### Pimoroni Trackball From b444d90b7882acc440bbf9d69f65e3e5343d927b Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Thu, 14 Jul 2022 07:05:21 -0700 Subject: [PATCH 04/10] Apply suggestions from review --- drivers/sensors/paw3204.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index cf8b77e52a22..417aba056836 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -76,20 +76,16 @@ uint8_t paw3204_serial_read(void) { void paw3204_serial_write(uint8_t data) { datatogglestate = readPin(PAW3204_SDIO_PIN); - if (datatogglestate == 1) { - writePinLow(PAW3204_SDIO_PIN); - } else { - writePinLow(PAW3204_SDIO_PIN); - } + writePinLow(PAW3204_SDIO_PIN); setPinOutput(PAW3204_SDIO_PIN); for (int8_t b = 7; b >= 0; b--) { writePinLow(PAW3204_SCLK_PIN); - if (data & (1 << b)) + if (data & (1 << b)) { writePinHigh(PAW3204_SDIO_PIN); - else + } else { writePinLow(PAW3204_SDIO_PIN); - // wait_us(2); + } writePinHigh(PAW3204_SCLK_PIN); } From 377107155ad2b173d502ec0e9a3658975717f178 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Thu, 14 Jul 2022 10:49:25 -0700 Subject: [PATCH 05/10] Also fix --- drivers/sensors/paw3204.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index 417aba056836..581ec5c348e9 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +// https://github.com/shinoaliceKabocha/choco60_track/tree/master/keymaps/default + #include "paw3204.h" #include "wait.h" #include "debug.h" @@ -93,10 +95,11 @@ void paw3204_serial_write(uint8_t data) { } int8_t convert_twoscomp(uint8_t data) { - if ((data & 0x80) == 0x80) + if ((data & 0x80) == 0x80) { return -128 + (data & 0x7F); - else + } else { return data; + } } report_paw3204_t paw3204_read(void) { From dabdb13ab7231abba0e4bc00429a85fe531afbde Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Thu, 14 Jul 2022 19:33:00 -0700 Subject: [PATCH 06/10] Apply suggestions from code review Co-authored-by: Stefan Kerkmann --- drivers/sensors/paw3204.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index 581ec5c348e9..571fb73f638f 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -21,7 +21,6 @@ #include "debug.h" #include "gpio.h" -uint8_t datatogglestate; #define REG_PID1 0x00 #define REG_PID2 0x01 #define REG_STAT 0x02 @@ -77,7 +76,7 @@ uint8_t paw3204_serial_read(void) { } void paw3204_serial_write(uint8_t data) { - datatogglestate = readPin(PAW3204_SDIO_PIN); + (void)readPin(PAW3204_SDIO_PIN); writePinLow(PAW3204_SDIO_PIN); setPinOutput(PAW3204_SDIO_PIN); @@ -106,8 +105,8 @@ report_paw3204_t paw3204_read(void) { report_paw3204_t data = {0}; data.isMotion = paw3204_read_reg(REG_STAT) & (1 << 7); // check for motion only (bit 7 in field) - data.x = convert_twoscomp(paw3204_read_reg(REG_X)); - data.y = convert_twoscomp(paw3204_read_reg(REG_Y)); + data.x = (int8_t)paw3204_read_reg(REG_X); + data.y = (int8_t)paw3204_read_reg(REG_Y); return data; } @@ -118,13 +117,9 @@ void paw3204_write_reg(uint8_t reg_addr, uint8_t data) { } uint8_t paw3204_read_reg(uint8_t reg_addr) { - uint8_t byte = 0; - paw3204_serial_write(reg_addr); wait_us(5); - byte = paw3204_serial_read(); - - return byte; + return paw3204_serial_read(); } void paw3204_set_cpi(uint16_t cpi) { From 831dbda794f02f281e0bff931ca38bf52af72b8f Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Thu, 14 Jul 2022 20:31:42 -0700 Subject: [PATCH 07/10] Remove unused functions --- drivers/sensors/paw3204.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index 571fb73f638f..247cef8625ce 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -93,14 +93,6 @@ void paw3204_serial_write(uint8_t data) { wait_us(4); } -int8_t convert_twoscomp(uint8_t data) { - if ((data & 0x80) == 0x80) { - return -128 + (data & 0x7F); - } else { - return data; - } -} - report_paw3204_t paw3204_read(void) { report_paw3204_t data = {0}; From 633737c186bd8b77d34d91511264ce74c67d8f79 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 19 Jul 2022 08:40:46 -0700 Subject: [PATCH 08/10] Apply suggestions from code review Co-authored-by: Stefan Kerkmann --- drivers/sensors/paw3204.c | 1 - drivers/sensors/paw3204.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index 247cef8625ce..82f37ba4216a 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -76,7 +76,6 @@ uint8_t paw3204_serial_read(void) { } void paw3204_serial_write(uint8_t data) { - (void)readPin(PAW3204_SDIO_PIN); writePinLow(PAW3204_SDIO_PIN); setPinOutput(PAW3204_SDIO_PIN); diff --git a/drivers/sensors/paw3204.h b/drivers/sensors/paw3204.h index e766b2f0305f..8ea03fc0a542 100644 --- a/drivers/sensors/paw3204.h +++ b/drivers/sensors/paw3204.h @@ -42,7 +42,6 @@ uint8_t paw3204_serial_read(void); void paw3204_serial_write(uint8_t reg_addr); uint8_t paw3204_read_reg(uint8_t reg_addr); void paw3204_write_reg(uint8_t reg_addr, uint8_t data); -int8_t convert_twoscomp(uint8_t data); uint8_t read_pid_paw3204(void); void paw3204_set_cpi(uint16_t cpi); uint16_t paw3204_get_cpi(void); From 1cad34e15b51fbf765759ce910cdcb213318e768 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 19 Jul 2022 08:49:14 -0700 Subject: [PATCH 09/10] Fix protos --- drivers/sensors/paw3204.c | 5 +++++ drivers/sensors/paw3204.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/sensors/paw3204.c b/drivers/sensors/paw3204.c index 82f37ba4216a..a13753dd6f1d 100644 --- a/drivers/sensors/paw3204.c +++ b/drivers/sensors/paw3204.c @@ -45,6 +45,11 @@ enum cpi_values { CPI1600, // 0b110 }; +uint8_t paw3204_serial_read(void); +void paw3204_serial_write(uint8_t reg_addr); +uint8_t paw3204_read_reg(uint8_t reg_addr); +void paw3204_write_reg(uint8_t reg_addr, uint8_t data); + void paw3204_init(void) { setPinOutput(PAW3204_SCLK_PIN); // setclockpin to output setPinInputHigh(PAW3204_SDIO_PIN); // set datapin input high diff --git a/drivers/sensors/paw3204.h b/drivers/sensors/paw3204.h index 8ea03fc0a542..f2f2168dba34 100644 --- a/drivers/sensors/paw3204.h +++ b/drivers/sensors/paw3204.h @@ -38,10 +38,5 @@ typedef struct { void paw3204_init(void); report_paw3204_t paw3204_read(void); -uint8_t paw3204_serial_read(void); -void paw3204_serial_write(uint8_t reg_addr); -uint8_t paw3204_read_reg(uint8_t reg_addr); -void paw3204_write_reg(uint8_t reg_addr, uint8_t data); -uint8_t read_pid_paw3204(void); void paw3204_set_cpi(uint16_t cpi); uint16_t paw3204_get_cpi(void); From 6b9bd527a9c4632ec2d5698bd9303f24b62ea629 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 19 Jul 2022 08:58:05 -0700 Subject: [PATCH 10/10] comments --- drivers/sensors/paw3204.h | 40 ++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/sensors/paw3204.h b/drivers/sensors/paw3204.h index f2f2168dba34..bf6dbd04a03e 100644 --- a/drivers/sensors/paw3204.h +++ b/drivers/sensors/paw3204.h @@ -29,14 +29,40 @@ typedef struct { int16_t x; int16_t y; - bool isMotion; + bool isMotion; } report_paw3204_t; -// A bunch of functions to implement the paw3204-specific serial protocol. -// Note that the "serial.h" driver is insufficient, because it does not -// manually manipulate a serial clock signal. +/** + * @brief Initializes the sensor so it is in a working state and ready to + * be polled for data. + * + * @return true Initialization was a success + * @return false Initialization failed, do not proceed operation + */ +void paw3204_init(void); + +/** + * @brief Reads and clears the current delta, and motion register values on the + * given sensor. + * + * @return pmw33xx_report_t Current values of the sensor, if errors occurred all + * fields are set to zero + */ -void paw3204_init(void); report_paw3204_t paw3204_read(void); -void paw3204_set_cpi(uint16_t cpi); -uint16_t paw3204_get_cpi(void); +/** + * @brief Sets the given CPI value the sensor. CPI is often refereed to + * as the sensors sensitivity. Values outside of the allowed range are + * constrained into legal values. + * + * @param cpi CPI value to set + */ +void paw3204_set_cpi(uint16_t cpi); + +/** + * @brief Gets the currently set CPI value from the sensor. CPI is often + * refereed to as the sensors sensitivity. + * + * @return uint16_t Current CPI value of the sensor + */ +uint16_t paw3204_get_cpi(void);