summaryrefslogtreecommitdiffstats
path: root/drivers/sensors
diff options
context:
space:
mode:
authoruqs <uqs@FreeBSD.org>2022-01-02 09:06:17 +0100
committerGitHub <noreply@github.com>2022-01-02 00:06:17 -0800
commit8b44eaa63eef60fa52c85838605a870d6f9d3e46 (patch)
tree6f28db53236825fca162a5cd0962dea7e23c6d77 /drivers/sensors
parent367e2bb0ff9d0481e5042c5420cb6e27fb770e56 (diff)
Update pmw3360 comments to match the datasheet better, fix delays. (#15682)
Diffstat (limited to 'drivers/sensors')
-rw-r--r--drivers/sensors/pmw3360.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/sensors/pmw3360.c b/drivers/sensors/pmw3360.c
index 4854ba5f47..9e3aeaa468 100644
--- a/drivers/sensors/pmw3360.c
+++ b/drivers/sensors/pmw3360.c
@@ -78,8 +78,12 @@
#define CPI_STEP 100
// clang-format on
+// limits to 0--119, resulting in a CPI range of 100 -- 12000 (as only steps of 100 are possible).
+// Note that for the PMW3389DM chip, the step size is 50 and supported range is
+// up to 16000. The datasheet does not indicate the minimum CPI though, neither
+// whether this uses 2 bytes (as 16000/50 == 320)
#ifndef MAX_CPI
-# define MAX_CPI 0x77 // limits to 0--119, should be max cpi/100
+# define MAX_CPI 0x77
#endif
bool _inBurst = false;
@@ -91,6 +95,7 @@ void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1'
bool pmw3360_spi_start(void) {
bool status = spi_start(PMW3360_CS_PIN, PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR);
+ // tNCS-SCLK, 120ns
wait_us(1);
return status;
}
@@ -106,12 +111,12 @@ spi_status_t pmw3360_write(uint8_t reg_addr, uint8_t data) {
spi_status_t status = spi_write(reg_addr | 0x80);
status = spi_write(data);
- // tSCLK-NCS for write operation
+ // tSCLK-NCS for write operation is 35us
wait_us(35);
+ spi_stop();
// tSWW/tSWR (=180us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
wait_us(145);
- spi_stop();
return status;
}
@@ -119,15 +124,16 @@ uint8_t pmw3360_read(uint8_t reg_addr) {
pmw3360_spi_start();
// send adress of the register, with MSBit = 0 to indicate it's a read
spi_write(reg_addr & 0x7f);
+ // tSRAD (=160us)
+ wait_us(160);
uint8_t data = spi_read();
// tSCLK-NCS for read operation is 120ns
wait_us(1);
+ spi_stop();
// tSRW/tSRR (=20us) minus tSCLK-NCS
wait_us(19);
-
- spi_stop();
return data;
}
@@ -149,7 +155,7 @@ bool pmw3360_init(void) {
spi_stop();
wait_us(40);
- // reboot
+ // power up, need to first drive NCS high then low, see above.
pmw3360_write(REG_Power_Up_Reset, 0x5a);
wait_ms(50);
@@ -190,6 +196,9 @@ bool pmw3360_init(void) {
}
void pmw3360_upload_firmware(void) {
+ // Datasheet claims we need to disable REST mode first, but during startup
+ // it's already disabled and we're not turning it on ...
+ //pmw3360_write(REG_Config2, 0x00); // disable REST mode
pmw3360_write(REG_SROM_Enable, 0x1d);
wait_ms(10);
@@ -242,15 +251,20 @@ report_pmw3360_t pmw3360_read_burst(void) {
pmw3360_spi_start();
spi_write(REG_Motion_Burst);
- wait_us(35); // waits for tSRAD
+ wait_us(35); // waits for tSRAD_MOTBR
report.motion = spi_read();
- spi_write(0x00); // skip Observation
+ spi_read(); // skip Observation
+ // delta registers
report.dx = spi_read();
report.mdx = spi_read();
report.dy = spi_read();
report.mdy = spi_read();
+ if (report.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
+ _inBurst = false;
+ }
+
spi_stop();
#ifdef CONSOLE_ENABLE
@@ -271,9 +285,5 @@ report_pmw3360_t pmw3360_read_burst(void) {
report.dy |= (report.mdy << 8);
report.dy = report.dy * -1;
- if (report.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
- _inBurst = false;
- }
-
return report;
}