diff options
Diffstat (limited to 'drivers/sensors/pmw3360.c')
| -rw-r--r-- | drivers/sensors/pmw3360.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/sensors/pmw3360.c b/drivers/sensors/pmw3360.c index 5463bfc59..2b27dccbb 100644 --- a/drivers/sensors/pmw3360.c +++ b/drivers/sensors/pmw3360.c | |||
| @@ -20,9 +20,10 @@ | |||
| 20 | #include "wait.h" | 20 | #include "wait.h" |
| 21 | #include "debug.h" | 21 | #include "debug.h" |
| 22 | #include "print.h" | 22 | #include "print.h" |
| 23 | #include "pmw3360_firmware.h" | 23 | #include PMW3360_FIRMWARE_H |
| 24 | 24 | ||
| 25 | // Registers | 25 | // Registers |
| 26 | // clang-format off | ||
| 26 | #define REG_Product_ID 0x00 | 27 | #define REG_Product_ID 0x00 |
| 27 | #define REG_Revision_ID 0x01 | 28 | #define REG_Revision_ID 0x01 |
| 28 | #define REG_Motion 0x02 | 29 | #define REG_Motion 0x02 |
| @@ -72,10 +73,18 @@ | |||
| 72 | #define REG_Lift_Config 0x63 | 73 | #define REG_Lift_Config 0x63 |
| 73 | #define REG_Raw_Data_Burst 0x64 | 74 | #define REG_Raw_Data_Burst 0x64 |
| 74 | #define REG_LiftCutoff_Tune2 0x65 | 75 | #define REG_LiftCutoff_Tune2 0x65 |
| 76 | // clang-format on | ||
| 77 | |||
| 78 | #ifndef MAX_CPI | ||
| 79 | # define MAX_CPI 0x77 // limits to 0--119, should be max cpi/100 | ||
| 80 | #endif | ||
| 75 | 81 | ||
| 76 | bool _inBurst = false; | 82 | bool _inBurst = false; |
| 77 | 83 | ||
| 84 | #ifdef CONSOLE_ENABLE | ||
| 78 | void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); } | 85 | void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); } |
| 86 | #endif | ||
| 87 | #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) | ||
| 79 | 88 | ||
| 80 | bool spi_start_adv(void) { | 89 | bool spi_start_adv(void) { |
| 81 | bool status = spi_start(PMW3360_CS_PIN, PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR); | 90 | bool status = spi_start(PMW3360_CS_PIN, PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR); |
| @@ -124,20 +133,20 @@ uint8_t spi_read_adv(uint8_t reg_addr) { | |||
| 124 | return data; | 133 | return data; |
| 125 | } | 134 | } |
| 126 | 135 | ||
| 127 | void pmw_set_cpi(uint16_t cpi) { | 136 | void pmw3360_set_cpi(uint16_t cpi) { |
| 128 | uint8_t cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119 | 137 | uint8_t cpival = constrain((cpi / 100) - 1, 0, MAX_CPI); |
| 129 | 138 | ||
| 130 | spi_start_adv(); | 139 | spi_start_adv(); |
| 131 | spi_write_adv(REG_Config1, cpival); | 140 | spi_write_adv(REG_Config1, cpival); |
| 132 | spi_stop(); | 141 | spi_stop(); |
| 133 | } | 142 | } |
| 134 | 143 | ||
| 135 | uint16_t pmw_get_cpi(void) { | 144 | uint16_t pmw3360_get_cpi(void) { |
| 136 | uint8_t cpival = spi_read_adv(REG_Config1); | 145 | uint8_t cpival = spi_read_adv(REG_Config1); |
| 137 | return (uint16_t)(cpival & 0xFF) * 100; | 146 | return (uint16_t)(cpival & 0xFF) * 100; |
| 138 | } | 147 | } |
| 139 | 148 | ||
| 140 | bool pmw_spi_init(void) { | 149 | bool pmw3360_init(void) { |
| 141 | setPinOutput(PMW3360_CS_PIN); | 150 | setPinOutput(PMW3360_CS_PIN); |
| 142 | 151 | ||
| 143 | spi_init(); | 152 | spi_init(); |
| @@ -164,12 +173,12 @@ bool pmw_spi_init(void) { | |||
| 164 | spi_read_adv(REG_Delta_Y_L); | 173 | spi_read_adv(REG_Delta_Y_L); |
| 165 | spi_read_adv(REG_Delta_Y_H); | 174 | spi_read_adv(REG_Delta_Y_H); |
| 166 | 175 | ||
| 167 | pmw_upload_firmware(); | 176 | pmw3360_upload_firmware(); |
| 168 | 177 | ||
| 169 | spi_stop_adv(); | 178 | spi_stop_adv(); |
| 170 | 179 | ||
| 171 | wait_ms(10); | 180 | wait_ms(10); |
| 172 | pmw_set_cpi(PMW3360_CPI); | 181 | pmw3360_set_cpi(PMW3360_CPI); |
| 173 | 182 | ||
| 174 | wait_ms(1); | 183 | wait_ms(1); |
| 175 | 184 | ||
| @@ -177,14 +186,14 @@ bool pmw_spi_init(void) { | |||
| 177 | 186 | ||
| 178 | spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30)); | 187 | spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30)); |
| 179 | 188 | ||
| 180 | bool init_success = pmw_check_signature(); | 189 | bool init_success = pmw3360_check_signature(); |
| 181 | 190 | ||
| 182 | writePinLow(PMW3360_CS_PIN); | 191 | writePinLow(PMW3360_CS_PIN); |
| 183 | 192 | ||
| 184 | return init_success; | 193 | return init_success; |
| 185 | } | 194 | } |
| 186 | 195 | ||
| 187 | void pmw_upload_firmware(void) { | 196 | void pmw3360_upload_firmware(void) { |
| 188 | spi_write_adv(REG_SROM_Enable, 0x1d); | 197 | spi_write_adv(REG_SROM_Enable, 0x1d); |
| 189 | 198 | ||
| 190 | wait_ms(10); | 199 | wait_ms(10); |
| @@ -211,16 +220,18 @@ void pmw_upload_firmware(void) { | |||
| 211 | wait_ms(10); | 220 | wait_ms(10); |
| 212 | } | 221 | } |
| 213 | 222 | ||
| 214 | bool pmw_check_signature(void) { | 223 | bool pmw3360_check_signature(void) { |
| 215 | uint8_t pid = spi_read_adv(REG_Product_ID); | 224 | uint8_t pid = spi_read_adv(REG_Product_ID); |
| 216 | uint8_t iv_pid = spi_read_adv(REG_Inverse_Product_ID); | 225 | uint8_t iv_pid = spi_read_adv(REG_Inverse_Product_ID); |
| 217 | uint8_t SROM_ver = spi_read_adv(REG_SROM_ID); | 226 | uint8_t SROM_ver = spi_read_adv(REG_SROM_ID); |
| 218 | return (pid == 0x42 && iv_pid == 0xBD && SROM_ver == 0x04); // signature for SROM 0x04 | 227 | return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04 |
| 219 | } | 228 | } |
| 220 | 229 | ||
| 221 | report_pmw_t pmw_read_burst(void) { | 230 | report_pmw3360_t pmw3360_read_burst(void) { |
| 222 | if (!_inBurst) { | 231 | if (!_inBurst) { |
| 232 | #ifdef CONSOLE_ENABLE | ||
| 223 | dprintf("burst on"); | 233 | dprintf("burst on"); |
| 234 | #endif | ||
| 224 | spi_write_adv(REG_Motion_Burst, 0x00); | 235 | spi_write_adv(REG_Motion_Burst, 0x00); |
| 225 | _inBurst = true; | 236 | _inBurst = true; |
| 226 | } | 237 | } |
| @@ -229,12 +240,7 @@ report_pmw_t pmw_read_burst(void) { | |||
| 229 | spi_write(REG_Motion_Burst); | 240 | spi_write(REG_Motion_Burst); |
| 230 | wait_us(35); // waits for tSRAD | 241 | wait_us(35); // waits for tSRAD |
| 231 | 242 | ||
| 232 | report_pmw_t data; | 243 | report_pmw3360_t data = {0}; |
| 233 | data.motion = 0; | ||
| 234 | data.dx = 0; | ||
| 235 | data.mdx = 0; | ||
| 236 | data.dy = 0; | ||
| 237 | data.mdx = 0; | ||
| 238 | 244 | ||
| 239 | data.motion = spi_read(); | 245 | data.motion = spi_read(); |
| 240 | spi_write(0x00); // skip Observation | 246 | spi_write(0x00); // skip Observation |
| @@ -245,6 +251,7 @@ report_pmw_t pmw_read_burst(void) { | |||
| 245 | 251 | ||
| 246 | spi_stop(); | 252 | spi_stop(); |
| 247 | 253 | ||
| 254 | #ifdef CONSOLE_ENABLE | ||
| 248 | if (debug_mouse) { | 255 | if (debug_mouse) { |
| 249 | print_byte(data.motion); | 256 | print_byte(data.motion); |
| 250 | print_byte(data.dx); | 257 | print_byte(data.dx); |
| @@ -253,6 +260,7 @@ report_pmw_t pmw_read_burst(void) { | |||
| 253 | print_byte(data.mdy); | 260 | print_byte(data.mdy); |
| 254 | dprintf("\n"); | 261 | dprintf("\n"); |
| 255 | } | 262 | } |
| 263 | #endif | ||
| 256 | 264 | ||
| 257 | data.isMotion = (data.motion & 0x80) != 0; | 265 | data.isMotion = (data.motion & 0x80) != 0; |
| 258 | data.isOnSurface = (data.motion & 0x08) == 0; | 266 | data.isOnSurface = (data.motion & 0x08) == 0; |
