Skip to content

Commit

Permalink
[Bug][Core] Fix optical sensor firmware upload (qmk#15919)
Browse files Browse the repository at this point in the history
  • Loading branch information
drashna committed Jan 21, 2022
1 parent d9f4dbc commit d6f32bd
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 28 deletions.
19 changes: 10 additions & 9 deletions docs/feature_pointing_device.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ POINTING_DEVICE_DRIVER = adns9800

The ADNS 9800 is an SPI driven optical sensor, that uses laser output for surface tracking.

| Setting | Description | Default |
|------------------------|------------------------------------------------------------------------|---------------|
|`ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|`ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|`ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|`ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|`ADNS9800_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
| Setting | Description | Default |
|--------------------------------|------------------------------------------------------------------------|---------------|
|`ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|`ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|`ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|`ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|`ADNS9800_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |


The CPI range is 800-8200, in increments of 200. Defaults to 1800 CPI.
Expand Down Expand Up @@ -150,8 +150,8 @@ The PMW 3360 is an SPI driven optical sensor, that uses a built in IR LED for su
|`PMW3360_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|`PMW3360_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|`PMW3360_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor. | `0` |
|`PMW3360_LEGACY_FIRMWARE_UPLOAD` | (Optional) Switches to older, manual upload of firmware, for compatibility. | _not defined_ |
|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor.| `0` |
|`PMW3360_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |

The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI.

Expand All @@ -174,6 +174,7 @@ The PMW 3389 is an SPI driven optical sensor, that uses a built in IR LED for su
|`PMW3389_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|`PMW3389_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 30 degrees directly in the sensor. | `0` |
|`PMW3389_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |

The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI.

Expand Down
6 changes: 2 additions & 4 deletions drivers/sensors/adns9800.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,8 @@ void adns9800_init() {
wait_us(15);

// send all bytes of the firmware
unsigned char c;
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
c = (unsigned char)pgm_read_byte(adns9800_firmware_data + i);
spi_write(c);
for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
spi_write(pgm_read_byte(firmware_data + i));
wait_us(15);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/sensors/adns9800_srom_A6.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

// clang-format off

const uint8_t adns9800_firmware_data[FIRMWARE_LENGTH] PROGMEM = {
const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = {
0x03, 0xA6, 0x68, 0x1E, 0x7D, 0x10, 0x7E, 0x7E, 0x5F, 0x1C, 0xB8, 0xF2, 0x47, 0x0C, 0x7B, 0x74,
0x4B, 0x14, 0x8B, 0x75, 0x66, 0x51, 0x0B, 0x8C, 0x76, 0x74, 0x4B, 0x14, 0xAA, 0xD6, 0x0F, 0x9C,
0xBA, 0xF6, 0x6E, 0x3F, 0xDD, 0x38, 0xD5, 0x02, 0x80, 0x9B, 0x82, 0x6D, 0x58, 0x13, 0xA4, 0xAB,
Expand Down
12 changes: 4 additions & 8 deletions drivers/sensors/pmw3360.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,12 @@ void pmw3360_upload_firmware(void) {
spi_write(REG_SROM_Load_Burst | 0x80);
wait_us(15);

#ifdef PMW3360_LEGACY_FIRMWARE_UPLOAD
unsigned char c;
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
c = (unsigned char)pgm_read_byte(firmware_data + i);
spi_write(c);
for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
spi_write(pgm_read_byte(firmware_data + i));
#ifndef PMW3360_FIRMWARE_UPLOAD_FAST
wait_us(15);
}
#else
spi_transmit(firmware_data, sizeof(firmware_data));
#endif
}
wait_us(200);

pmw3360_read(REG_SROM_ID);
Expand Down
10 changes: 4 additions & 6 deletions drivers/sensors/pmw3389.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,12 @@ void pmw3389_upload_firmware(void) {
spi_write(REG_SROM_Load_Burst | 0x80);
wait_us(15);

// legacy only for PMW3389 spi_transmit failed to load firmware
unsigned char c;
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
c = (unsigned char)pgm_read_byte(firmware_data + i);
spi_write(c);
for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
spi_write(pgm_read_byte(firmware_data + i));
#ifndef PMW3389_FIRMWARE_UPLOAD_FAST
wait_us(15);
#endif
}

wait_us(200);

pmw3389_read(REG_SROM_ID);
Expand Down

0 comments on commit d6f32bd

Please sign in to comment.