Move optical sensor code to drivers folder (#13044)
This commit is contained in:
		
							parent
							
								
									b491c7994a
								
							
						
					
					
						commit
						6901411bca
					
				| @ -19,20 +19,16 @@ | ||||
| 
 | ||||
| 
 | ||||
| #include "adns5050.h" | ||||
| #include "quantum.h" | ||||
| #include "wait.h" | ||||
| 
 | ||||
| #ifdef CONSOLE_ENABLE | ||||
| #    include "print.h" | ||||
| #endif | ||||
| #include "debug.h" | ||||
| #include "print.h" | ||||
| #include "gpio.h" | ||||
| 
 | ||||
| #ifndef OPTIC_ROTATED | ||||
| #    define OPTIC_ROTATED false | ||||
| #endif | ||||
| 
 | ||||
| // Definitions for the ADNS serial line.
 | ||||
| // These really ought to be defined in your config.h, but defaults are
 | ||||
| // here if you're really lazy.
 | ||||
| #ifndef ADNS_SCLK_PIN | ||||
| #    define ADNS_SCLK_PIN B7 | ||||
| #endif | ||||
| @ -17,7 +17,7 @@ | ||||
| #include "spi_master.h" | ||||
| #include "quantum.h" | ||||
| #include "adns9800_srom_A6.h" | ||||
| #include "adns.h" | ||||
| #include "adns9800.h" | ||||
| 
 | ||||
| // registers
 | ||||
| #define REG_Product_ID                           0x00 | ||||
| @ -26,8 +26,8 @@ static float   precisionSpeed = 1; | ||||
| 
 | ||||
| static uint16_t i2c_timeout_timer; | ||||
| 
 | ||||
| #ifndef I2C_TIMEOUT | ||||
| #    define I2C_TIMEOUT 100 | ||||
| #ifndef PIMORONI_I2C_TIMEOUT | ||||
| #    define PIMORONI_I2C_TIMEOUT 100 | ||||
| #endif | ||||
| #ifndef I2C_WAITCHECK | ||||
| #    define I2C_WAITCHECK 1000 | ||||
| @ -38,7 +38,7 @@ static uint16_t i2c_timeout_timer; | ||||
| 
 | ||||
| void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { | ||||
|     uint8_t data[] = {0x00, red, green, blue, white}; | ||||
|     i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), I2C_TIMEOUT); | ||||
|     i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), PIMORONI_I2C_TIMEOUT); | ||||
| } | ||||
| 
 | ||||
| int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) { | ||||
| @ -68,59 +68,19 @@ __attribute__((weak)) void trackball_check_click(bool pressed, report_mouse_t* m | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | ||||
|     if (true) { | ||||
|         xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     if (!process_record_user(keycode, record)) { return false; } | ||||
| 
 | ||||
| /* If Mousekeys is disabled, then use handle the mouse button
 | ||||
|  * keycodes.  This makes things simpler, and allows usage of | ||||
|  * the keycodes in a consistent manner.  But only do this if | ||||
|  * Mousekeys is not enable, so it's not handled twice. | ||||
|  */ | ||||
| #ifndef MOUSEKEY_ENABLE | ||||
|     if (IS_MOUSEKEY_BUTTON(keycode)) { | ||||
|         report_mouse_t currentReport = pointing_device_get_report(); | ||||
|         if (record->event.pressed) { | ||||
|             currentReport.buttons |= 1 << (keycode - KC_MS_BTN1); | ||||
|         } else { | ||||
|             currentReport.buttons &= ~(1 << (keycode - KC_MS_BTN1)); | ||||
|         } | ||||
|         pointing_device_set_report(currentReport); | ||||
|         pointing_device_send(); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void trackball_register_button(bool pressed, enum mouse_buttons button) { | ||||
|     report_mouse_t currentReport = pointing_device_get_report(); | ||||
|     if (pressed) { | ||||
|         currentReport.buttons |= button; | ||||
|     } else { | ||||
|         currentReport.buttons &= ~button; | ||||
|     } | ||||
|     pointing_device_set_report(currentReport); | ||||
| } | ||||
| 
 | ||||
| float trackball_get_precision(void) { return precisionSpeed; } | ||||
| void  trackball_set_precision(float precision) { precisionSpeed = precision; } | ||||
| bool  trackball_is_scrolling(void) { return scrolling; } | ||||
| void  trackball_set_scrolling(bool scroll) { scrolling = scroll; } | ||||
| 
 | ||||
| 
 | ||||
| __attribute__((weak)) void pointing_device_init(void) { trackball_set_rgbw(0x80, 0x00, 0x00, 0x00); } | ||||
| __attribute__((weak)) void pointing_device_init(void) { i2c_init(); trackball_set_rgbw(0x00, 0x00, 0x00, 0x00); } | ||||
| 
 | ||||
| void pointing_device_task(void) { | ||||
|     static bool     debounce; | ||||
|     static uint16_t debounce_timer; | ||||
|     uint8_t         state[5] = {}; | ||||
|     if (timer_elapsed(i2c_timeout_timer) > I2C_WAITCHECK) { | ||||
|         if (i2c_readReg(TRACKBALL_WRITE, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { | ||||
|         if (i2c_readReg(TRACKBALL_READ, 0x04, state, 5, PIMORONI_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { | ||||
|             if (!state[4] && !debounce) { | ||||
|                 if (scrolling) { | ||||
| #ifdef PIMORONI_TRACKBALL_INVERT_X | ||||
| @ -159,7 +119,10 @@ void pointing_device_task(void) { | ||||
|     if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false; | ||||
| 
 | ||||
|     report_mouse_t mouse = pointing_device_get_report(); | ||||
|     // trackball_check_click(state[4] & (1 << 7), &mouse);
 | ||||
| 
 | ||||
| #ifdef PIMORONI_TRACKBALL_CLICK | ||||
|     trackball_check_click(state[4] & (1 << 7), &mouse); | ||||
| #endif | ||||
| 
 | ||||
| #ifndef PIMORONI_TRACKBALL_ROTATE | ||||
|     update_member(&mouse.x, &x_offset); | ||||
| @ -16,8 +16,6 @@ | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #ifdef POINTING_DEVICE_ENABLE | ||||
| 
 | ||||
| #include "wait.h" | ||||
| #include "debug.h" | ||||
| #include "print.h" | ||||
| @ -29,17 +27,26 @@ bool _inBurst = false; | ||||
| #ifndef PMW_CPI | ||||
| #    define PMW_CPI 1600 | ||||
| #endif | ||||
| #ifndef PMW_CLOCK_SPEED | ||||
| #    define PMW_CLOCK_SPEED 70000000 | ||||
| #endif | ||||
| #ifndef SPI_MODE | ||||
| #    define SPI_MODE 3 | ||||
| #endif | ||||
| #ifndef SPI_DIVISOR | ||||
| #    define SPI_DIVISOR 2 | ||||
| #    define SPI_DIVISOR (F_CPU / PMW_CLOCK_SPEED) | ||||
| #endif | ||||
| #ifndef ROTATIONAL_TRANSFORM_ANGLE | ||||
| #    define ROTATIONAL_TRANSFORM_ANGLE 0x00 | ||||
| #endif | ||||
| #ifndef PMW_CS_PIN | ||||
| #    define PMW_CS_PIN SPI_SS_PIN | ||||
| #endif | ||||
| 
 | ||||
| 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')); } | ||||
| 
 | ||||
| bool spi_start_adv(void) { | ||||
|     bool status = spi_start(SPI_SS_PIN, false, 3, SPI_DIVISOR); | ||||
|     bool status = spi_start(PMW_CS_PIN, false, SPI_MODE, SPI_DIVISOR); | ||||
|     wait_us(1); | ||||
|     return status; | ||||
| } | ||||
| @ -57,7 +64,7 @@ spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data) { | ||||
|     spi_start_adv(); | ||||
|     // send address of the register, with MSBit = 1 to indicate it's a write
 | ||||
|     spi_status_t status = spi_write(reg_addr | 0x80); | ||||
|     status = spi_write(data); | ||||
|     status              = spi_write(data); | ||||
| 
 | ||||
|     // tSCLK-NCS for write operation
 | ||||
|     wait_us(20); | ||||
| @ -86,14 +93,21 @@ uint8_t spi_read_adv(uint8_t reg_addr) { | ||||
| } | ||||
| 
 | ||||
| void pmw_set_cpi(uint16_t cpi) { | ||||
|     int cpival = constrain((cpi / 100) - 1, 0, 0x77);  // limits to 0--119
 | ||||
|     uint8_t cpival = constrain((cpi / 100) - 1, 0, 0x77);  // limits to 0--119
 | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
|     spi_write_adv(REG_Config1, cpival); | ||||
|     spi_stop(); | ||||
| } | ||||
| 
 | ||||
| uint16_t pmw_get_cpi(void) { | ||||
|     uint8_t cpival = spi_read_adv(REG_Config1); | ||||
|     return (uint16_t)(cpival & 0xFF) * 100; | ||||
| } | ||||
| 
 | ||||
| bool pmw_spi_init(void) { | ||||
|     setPinOutput(PMW_CS_PIN); | ||||
| 
 | ||||
|     spi_init(); | ||||
|     _inBurst = false; | ||||
| 
 | ||||
| @ -101,7 +115,7 @@ bool pmw_spi_init(void) { | ||||
|     spi_start_adv(); | ||||
|     spi_stop(); | ||||
| 
 | ||||
|     spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first
 | ||||
|     spi_write_adv(REG_Shutdown, 0xb6);  // Shutdown first
 | ||||
|     wait_ms(300); | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
| @ -127,14 +141,18 @@ bool pmw_spi_init(void) { | ||||
| 
 | ||||
|     wait_ms(1); | ||||
| 
 | ||||
|     return pmw_check_signature(); | ||||
| } | ||||
| 
 | ||||
| void pmw_upload_firmware(void) { | ||||
|     spi_write_adv(REG_Config2, 0x00); | ||||
| 
 | ||||
|     spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30)); | ||||
| 
 | ||||
|     bool init_success = pmw_check_signature(); | ||||
| 
 | ||||
|     writePinLow(PMW_CS_PIN); | ||||
| 
 | ||||
|     return init_success; | ||||
| } | ||||
| 
 | ||||
| void pmw_upload_firmware(void) { | ||||
|     spi_write_adv(REG_SROM_Enable, 0x1d); | ||||
| 
 | ||||
|     wait_ms(10); | ||||
| @ -217,5 +235,3 @@ report_pmw_t pmw_read_burst(void) { | ||||
| 
 | ||||
|     return data; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| @ -93,6 +93,7 @@ spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data); | ||||
| uint8_t spi_read_adv(uint8_t reg_addr); | ||||
| bool pmw_spi_init(void); | ||||
| void pmw_set_cpi(uint16_t cpi); | ||||
| uint16_t pmw_get_cpi(void); | ||||
| void pmw_upload_firmware(void); | ||||
| bool pmw_check_signature(void); | ||||
| report_pmw_t pmw_read_burst(void); | ||||
| @ -16,7 +16,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
| 
 | ||||
| #include QMK_KEYBOARD_H | ||||
| #include "pimoroni_trackball.h" | ||||
| #include "drivers/sensors/pimoroni_trackball.h" | ||||
| #include "pointing_device.h" | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,35 +0,0 @@ | ||||
| /* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "pointing_device.h" | ||||
| 
 | ||||
| #ifndef TRACKBALL_ADDRESS | ||||
| #    define TRACKBALL_ADDRESS 0x0A | ||||
| #endif | ||||
| #define TRACKBALL_WRITE ((TRACKBALL_ADDRESS << 1) | I2C_WRITE) | ||||
| #define TRACKBALL_READ  ((TRACKBALL_ADDRESS << 1) | I2C_READ) | ||||
| 
 | ||||
| void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white); | ||||
| void trackball_check_click(bool pressed, report_mouse_t *mouse); | ||||
| void trackball_register_button(bool pressed, enum mouse_buttons button); | ||||
| 
 | ||||
| float trackball_get_precision(void); | ||||
| void    trackball_set_precision(float precision); | ||||
| bool    trackball_is_scrolling(void); | ||||
| void    trackball_set_scrolling(bool scroll); | ||||
| @ -1,6 +1,6 @@ | ||||
| # only uncomment on the side you have your trackball on
 | ||||
| POINTING_DEVICE_ENABLE = yes | ||||
| SRC += pimoroni_trackball.c | ||||
| SRC += drivers/sensors/pimoroni_trackball.c | ||||
| QUANTUM_LIB_SRC += i2c_master.c | ||||
| OLED_DRIVER_ENABLE = yes | ||||
| MOUSEKEY_ENABLE = no | ||||
|  | ||||
| @ -19,7 +19,7 @@ | ||||
| #include "dactyl_manuform.h" | ||||
| #include "quantum.h" | ||||
| #include "spi_master.h" | ||||
| #include "pmw3360.h" | ||||
| #include "drivers/sensors/pmw3360.h" | ||||
| #include "pointing_device.h" | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,103 +0,0 @@ | ||||
| /* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | ||||
|  * Copyright 2019 Sunjun Kim | ||||
|  * Copyright 2020 Ploopy Corporation | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "spi_master.h" | ||||
| 
 | ||||
| // Registers
 | ||||
| #define REG_Product_ID  0x00 | ||||
| #define REG_Revision_ID 0x01 | ||||
| #define REG_Motion  0x02 | ||||
| #define REG_Delta_X_L 0x03 | ||||
| #define REG_Delta_X_H 0x04 | ||||
| #define REG_Delta_Y_L 0x05 | ||||
| #define REG_Delta_Y_H 0x06 | ||||
| #define REG_SQUAL 0x07 | ||||
| #define REG_Raw_Data_Sum  0x08 | ||||
| #define REG_Maximum_Raw_data  0x09 | ||||
| #define REG_Minimum_Raw_data  0x0A | ||||
| #define REG_Shutter_Lower 0x0B | ||||
| #define REG_Shutter_Upper 0x0C | ||||
| #define REG_Control 0x0D | ||||
| #define REG_Config1 0x0F | ||||
| #define REG_Config2 0x10 | ||||
| #define REG_Angle_Tune  0x11 | ||||
| #define REG_Frame_Capture 0x12 | ||||
| #define REG_SROM_Enable 0x13 | ||||
| #define REG_Run_Downshift 0x14 | ||||
| #define REG_Rest1_Rate_Lower  0x15 | ||||
| #define REG_Rest1_Rate_Upper  0x16 | ||||
| #define REG_Rest1_Downshift 0x17 | ||||
| #define REG_Rest2_Rate_Lower  0x18 | ||||
| #define REG_Rest2_Rate_Upper  0x19 | ||||
| #define REG_Rest2_Downshift 0x1A | ||||
| #define REG_Rest3_Rate_Lower  0x1B | ||||
| #define REG_Rest3_Rate_Upper  0x1C | ||||
| #define REG_Observation 0x24 | ||||
| #define REG_Data_Out_Lower  0x25 | ||||
| #define REG_Data_Out_Upper  0x26 | ||||
| #define REG_Raw_Data_Dump 0x29 | ||||
| #define REG_SROM_ID 0x2A | ||||
| #define REG_Min_SQ_Run  0x2B | ||||
| #define REG_Raw_Data_Threshold  0x2C | ||||
| #define REG_Config5 0x2F | ||||
| #define REG_Power_Up_Reset  0x3A | ||||
| #define REG_Shutdown  0x3B | ||||
| #define REG_Inverse_Product_ID  0x3F | ||||
| #define REG_LiftCutoff_Tune3  0x41 | ||||
| #define REG_Angle_Snap  0x42 | ||||
| #define REG_LiftCutoff_Tune1  0x4A | ||||
| #define REG_Motion_Burst  0x50 | ||||
| #define REG_LiftCutoff_Tune_Timeout 0x58 | ||||
| #define REG_LiftCutoff_Tune_Min_Length  0x5A | ||||
| #define REG_SROM_Load_Burst 0x62 | ||||
| #define REG_Lift_Config 0x63 | ||||
| #define REG_Raw_Data_Burst  0x64 | ||||
| #define REG_LiftCutoff_Tune2  0x65 | ||||
| 
 | ||||
| #ifdef CONSOLE_ENABLE | ||||
| void print_byte(uint8_t byte); | ||||
| #endif | ||||
| 
 | ||||
| typedef struct { | ||||
|     int8_t  motion; | ||||
|     bool    isMotion;     // True if a motion is detected.
 | ||||
|     bool    isOnSurface;  // True when a chip is on a surface
 | ||||
|     int16_t dx;           // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
 | ||||
|     int8_t  mdx; | ||||
|     int16_t dy;  // displacement on y directions.
 | ||||
|     int8_t  mdy; | ||||
| } report_pmw_t; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| bool spi_start_adv(void); | ||||
| void spi_stop_adv(void); | ||||
| spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data); | ||||
| uint8_t spi_read_adv(uint8_t reg_addr); | ||||
| bool pmw_spi_init(void); | ||||
| void pmw_set_cpi(uint16_t cpi); | ||||
| void pmw_upload_firmware(void); | ||||
| bool pmw_check_signature(void); | ||||
| report_pmw_t pmw_read_burst(void); | ||||
| 
 | ||||
| 
 | ||||
| #define degToRad(angleInDegrees) ((angleInDegrees)*M_PI / 180.0) | ||||
| #define radToDeg(angleInRadians) ((angleInRadians)*180.0 / M_PI) | ||||
| #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) | ||||
| @ -27,5 +27,5 @@ MOUSE_SHARED_EP = no | ||||
| SPLIT_KEYBOARD = yes | ||||
| SPLIT_TRANSPORT = custom | ||||
| 
 | ||||
| SRC += pmw3360.c | ||||
| SRC += drivers/sensors/pmw3360.c | ||||
| QUANTUM_LIB_SRC += pointer_transport.c serial.c i2c_master.c i2c_slave.c spi_master.c | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| /* common interface for opitcal sensors */ | ||||
| 
 | ||||
| #if defined ADNS_9800 | ||||
|     #include "../adns/adns.h" | ||||
|     #include "drivers/sensors/adns9800.h" | ||||
|     #define config_optical_sensor_t config_adns_t | ||||
|     #define report_optical_sensor_t report_adns_t | ||||
|     #define optical_sensor_init adns_init | ||||
|  | ||||
| @ -25,5 +25,5 @@ POINTING_DEVICE_ENABLE = yes | ||||
| DEFAULT_FOLDER = oddball/v1 | ||||
| 
 | ||||
| SRC += spi_master.c | ||||
| SRC += adns/adns.c | ||||
| SRC += drivers/sensors/adns9800.c | ||||
| SRC += pmw/pmw.c | ||||
|  | ||||
| @ -20,7 +20,7 @@ | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "spi_master.h" | ||||
| #include "pmw3360.h" | ||||
| #include "drivers/sensors/pmw3360.h" | ||||
| #include "analog.h" | ||||
| #include "opt_encoder.h" | ||||
| #include "pointing_device.h" | ||||
|  | ||||
| @ -27,4 +27,4 @@ POINTING_DEVICE_ENABLE = yes | ||||
| MOUSEKEY_ENABLE = yes       # Mouse keys | ||||
| 
 | ||||
| QUANTUM_LIB_SRC += analog.c spi_master.c | ||||
| SRC += pmw3360.c opt_encoder.c | ||||
| SRC += drivers/sensors/pmw3360.c opt_encoder.c | ||||
|  | ||||
| @ -1,218 +0,0 @@ | ||||
| /* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | ||||
|  * Copyright 2019 Sunjun Kim | ||||
|  * Copyright 2020 Ploopy Corporation | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include "wait.h" | ||||
| #include "debug.h" | ||||
| #include "print.h" | ||||
| #include "pmw3360.h" | ||||
| #include "pmw3360_firmware.h" | ||||
| 
 | ||||
| bool _inBurst = false; | ||||
| 
 | ||||
| #ifndef PMW_CPI | ||||
| #    define PMW_CPI 1600 | ||||
| #endif | ||||
| #ifndef SPI_DIVISOR | ||||
| #    define SPI_DIVISOR 2 | ||||
| #endif | ||||
| #ifndef ROTATIONAL_TRANSFORM_ANGLE | ||||
| #    define ROTATIONAL_TRANSFORM_ANGLE 0x00 | ||||
| #endif | ||||
| 
 | ||||
| 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')); } | ||||
| 
 | ||||
| 
 | ||||
| bool spi_start_adv(void) { | ||||
|     bool status = spi_start(SPI_SS_PIN, false, 3, SPI_DIVISOR); | ||||
|     wait_us(1); | ||||
|     return status; | ||||
| } | ||||
| 
 | ||||
| void spi_stop_adv(void) { | ||||
|     wait_us(1); | ||||
|     spi_stop(); | ||||
| } | ||||
| 
 | ||||
| spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data) { | ||||
|     if (reg_addr != REG_Motion_Burst) { | ||||
|         _inBurst = false; | ||||
|     } | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
|     // send address of the register, with MSBit = 1 to indicate it's a write
 | ||||
|     spi_status_t status = spi_write(reg_addr | 0x80); | ||||
|     status = spi_write(data); | ||||
| 
 | ||||
|     // tSCLK-NCS for write operation
 | ||||
|     wait_us(20); | ||||
| 
 | ||||
|     // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
 | ||||
|     wait_us(100); | ||||
|     spi_stop(); | ||||
|     return status; | ||||
| } | ||||
| 
 | ||||
| uint8_t spi_read_adv(uint8_t reg_addr) { | ||||
|     spi_start_adv(); | ||||
|     // send adress of the register, with MSBit = 0 to indicate it's a read
 | ||||
|     spi_write(reg_addr & 0x7f); | ||||
| 
 | ||||
|     uint8_t data = spi_read(); | ||||
| 
 | ||||
|     // tSCLK-NCS for read operation is 120ns
 | ||||
|     wait_us(1); | ||||
| 
 | ||||
|     //  tSRW/tSRR (=20us) minus tSCLK-NCS
 | ||||
|     wait_us(19); | ||||
| 
 | ||||
|     spi_stop(); | ||||
|     return data; | ||||
| } | ||||
| 
 | ||||
| void pmw_set_cpi(uint16_t cpi) { | ||||
|     int cpival = constrain((cpi / 100) - 1, 0, 0x77);  // limits to 0--119
 | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
|     spi_write_adv(REG_Config1, cpival); | ||||
|     spi_stop(); | ||||
| } | ||||
| 
 | ||||
| bool pmw_spi_init(void) { | ||||
|     spi_init(); | ||||
|     _inBurst = false; | ||||
| 
 | ||||
|     spi_stop(); | ||||
|     spi_start_adv(); | ||||
|     spi_stop(); | ||||
| 
 | ||||
|     spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first
 | ||||
|     wait_ms(300); | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
|     wait_us(40); | ||||
|     spi_stop_adv(); | ||||
|     wait_us(40); | ||||
| 
 | ||||
|     spi_write_adv(REG_Power_Up_Reset, 0x5a); | ||||
|     wait_ms(50); | ||||
| 
 | ||||
|     spi_read_adv(REG_Motion); | ||||
|     spi_read_adv(REG_Delta_X_L); | ||||
|     spi_read_adv(REG_Delta_X_H); | ||||
|     spi_read_adv(REG_Delta_Y_L); | ||||
|     spi_read_adv(REG_Delta_Y_H); | ||||
| 
 | ||||
|     pmw_upload_firmware(); | ||||
| 
 | ||||
|     spi_stop_adv(); | ||||
| 
 | ||||
|     wait_ms(10); | ||||
|     pmw_set_cpi(PMW_CPI); | ||||
| 
 | ||||
|     wait_ms(1); | ||||
| 
 | ||||
|     return pmw_check_signature(); | ||||
| } | ||||
| 
 | ||||
| void pmw_upload_firmware(void) { | ||||
|     spi_write_adv(REG_Config2, 0x00); | ||||
| 
 | ||||
|     spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30)); | ||||
| 
 | ||||
|     spi_write_adv(REG_SROM_Enable, 0x1d); | ||||
| 
 | ||||
|     wait_ms(10); | ||||
| 
 | ||||
|     spi_write_adv(REG_SROM_Enable, 0x18); | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
|     spi_write(REG_SROM_Load_Burst | 0x80); | ||||
|     wait_us(15); | ||||
| 
 | ||||
|     unsigned char c; | ||||
|     for (int i = 0; i < firmware_length; i++) { | ||||
|         c = (unsigned char)pgm_read_byte(firmware_data + i); | ||||
|         spi_write(c); | ||||
|         wait_us(15); | ||||
|     } | ||||
|     wait_us(200); | ||||
| 
 | ||||
|     spi_read_adv(REG_SROM_ID); | ||||
| 
 | ||||
|     spi_write_adv(REG_Config2, 0x00); | ||||
| 
 | ||||
|     spi_stop(); | ||||
|     wait_ms(10); | ||||
| } | ||||
| 
 | ||||
| bool pmw_check_signature(void) { | ||||
|     uint8_t pid      = spi_read_adv(REG_Product_ID); | ||||
|     uint8_t iv_pid   = spi_read_adv(REG_Inverse_Product_ID); | ||||
|     uint8_t SROM_ver = spi_read_adv(REG_SROM_ID); | ||||
|     return (pid == 0x42 && iv_pid == 0xBD && SROM_ver == 0x04);  // signature for SROM 0x04
 | ||||
| } | ||||
| 
 | ||||
| report_pmw_t pmw_read_burst(void) { | ||||
|     if (!_inBurst) { | ||||
|         dprintf("burst on"); | ||||
|         spi_write_adv(REG_Motion_Burst, 0x00); | ||||
|         _inBurst = true; | ||||
|     } | ||||
| 
 | ||||
|     spi_start_adv(); | ||||
|     spi_write(REG_Motion_Burst); | ||||
|     wait_us(35);  // waits for tSRAD
 | ||||
| 
 | ||||
|     report_pmw_t data; | ||||
|     data.motion = 0; | ||||
|     data.dx     = 0; | ||||
|     data.mdx    = 0; | ||||
|     data.dy     = 0; | ||||
|     data.mdx    = 0; | ||||
| 
 | ||||
|     data.motion = spi_read(); | ||||
|     spi_write(0x00);  // skip Observation
 | ||||
|     data.dx  = spi_read(); | ||||
|     data.mdx = spi_read(); | ||||
|     data.dy  = spi_read(); | ||||
|     data.mdy = spi_read(); | ||||
| 
 | ||||
|     spi_stop(); | ||||
| 
 | ||||
|     print_byte(data.motion); | ||||
|     print_byte(data.dx); | ||||
|     print_byte(data.mdx); | ||||
|     print_byte(data.dy); | ||||
|     print_byte(data.mdy); | ||||
|     dprintf("\n"); | ||||
| 
 | ||||
|     data.isMotion    = (data.motion & 0x80) != 0; | ||||
|     data.isOnSurface = (data.motion & 0x08) == 0; | ||||
|     data.dx |= (data.mdx << 8); | ||||
|     data.dx = data.dx * -1; | ||||
|     data.dy |= (data.mdy << 8); | ||||
|     data.dy = data.dy * -1; | ||||
| 
 | ||||
|     spi_stop(); | ||||
| 
 | ||||
|     if (data.motion & 0b111) {  // panic recovery, sometimes burst mode works weird.
 | ||||
|         _inBurst = false; | ||||
|     } | ||||
| 
 | ||||
|     return data; | ||||
| } | ||||
| @ -1,300 +0,0 @@ | ||||
| /* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | ||||
|  * Copyright 2019 Sunjun Kim | ||||
|  * Copyright 2020 Ploopy Corporation | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| // clang-format off
 | ||||
| // Firmware Blob foor PMW3360
 | ||||
| const uint16_t firmware_length = 4094; | ||||
| // clang-format off
 | ||||
| const uint8_t firmware_data[] PROGMEM = {    // SROM 0x04
 | ||||
| 0x01, 0x04, 0x8e, 0x96, 0x6e, 0x77, 0x3e, 0xfe, 0x7e, 0x5f, 0x1d, 0xb8, 0xf2, 0x66, 0x4e, | ||||
| 0xff, 0x5d, 0x19, 0xb0, 0xc2, 0x04, 0x69, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0xb0, | ||||
| 0xc3, 0xe5, 0x29, 0xb1, 0xe0, 0x23, 0xa5, 0xa9, 0xb1, 0xc1, 0x00, 0x82, 0x67, 0x4c, 0x1a, | ||||
| 0x97, 0x8d, 0x79, 0x51, 0x20, 0xc7, 0x06, 0x8e, 0x7c, 0x7c, 0x7a, 0x76, 0x4f, 0xfd, 0x59, | ||||
| 0x30, 0xe2, 0x46, 0x0e, 0x9e, 0xbe, 0xdf, 0x1d, 0x99, 0x91, 0xa0, 0xa5, 0xa1, 0xa9, 0xd0, | ||||
| 0x22, 0xc6, 0xef, 0x5c, 0x1b, 0x95, 0x89, 0x90, 0xa2, 0xa7, 0xcc, 0xfb, 0x55, 0x28, 0xb3, | ||||
| 0xe4, 0x4a, 0xf7, 0x6c, 0x3b, 0xf4, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x05, | ||||
| 0x88, 0x92, 0xa6, 0xce, 0x1e, 0xbe, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x07, | ||||
| 0x11, 0x5d, 0x98, 0x0b, 0x9d, 0x94, 0x97, 0xee, 0x4e, 0x45, 0x33, 0x6b, 0x44, 0xc7, 0x29, | ||||
| 0x56, 0x27, 0x30, 0xc6, 0xa7, 0xd5, 0xf2, 0x56, 0xdf, 0xb4, 0x38, 0x62, 0xcb, 0xa0, 0xb6, | ||||
| 0xe3, 0x0f, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6f, 0x76, 0x89, 0xb5, 0x77, 0x41, 0x27, 0x82, | ||||
| 0x66, 0x65, 0x82, 0xcc, 0xd5, 0xe6, 0x20, 0xd5, 0x27, 0x17, 0xc5, 0xf8, 0x03, 0x23, 0x7c, | ||||
| 0x5f, 0x64, 0xa5, 0x1d, 0xc1, 0xd6, 0x36, 0xcb, 0x4c, 0xd4, 0xdb, 0x66, 0xd7, 0x8b, 0xb1, | ||||
| 0x99, 0x7e, 0x6f, 0x4c, 0x36, 0x40, 0x06, 0xd6, 0xeb, 0xd7, 0xa2, 0xe4, 0xf4, 0x95, 0x51, | ||||
| 0x5a, 0x54, 0x96, 0xd5, 0x53, 0x44, 0xd7, 0x8c, 0xe0, 0xb9, 0x40, 0x68, 0xd2, 0x18, 0xe9, | ||||
| 0xdd, 0x9a, 0x23, 0x92, 0x48, 0xee, 0x7f, 0x43, 0xaf, 0xea, 0x77, 0x38, 0x84, 0x8c, 0x0a, | ||||
| 0x72, 0xaf, 0x69, 0xf8, 0xdd, 0xf1, 0x24, 0x83, 0xa3, 0xf8, 0x4a, 0xbf, 0xf5, 0x94, 0x13, | ||||
| 0xdb, 0xbb, 0xd8, 0xb4, 0xb3, 0xa0, 0xfb, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, | ||||
| 0xa2, 0xd3, 0x13, 0xe7, 0xfa, 0xe7, 0xce, 0x0f, 0x63, 0x15, 0x0b, 0x6b, 0x94, 0xbb, 0x37, | ||||
| 0x83, 0x26, 0x05, 0x9d, 0xfb, 0x46, 0x92, 0xfc, 0x0a, 0x15, 0xd1, 0x0d, 0x73, 0x92, 0xd6, | ||||
| 0x8c, 0x1b, 0x8c, 0xb8, 0x55, 0x8a, 0xce, 0xbd, 0xfe, 0x8e, 0xfc, 0xed, 0x09, 0x12, 0x83, | ||||
| 0x91, 0x82, 0x51, 0x31, 0x23, 0xfb, 0xb4, 0x0c, 0x76, 0xad, 0x7c, 0xd9, 0xb4, 0x4b, 0xb2, | ||||
| 0x67, 0x14, 0x09, 0x9c, 0x7f, 0x0c, 0x18, 0xba, 0x3b, 0xd6, 0x8e, 0x14, 0x2a, 0xe4, 0x1b, | ||||
| 0x52, 0x9f, 0x2b, 0x7d, 0xe1, 0xfb, 0x6a, 0x33, 0x02, 0xfa, 0xac, 0x5a, 0xf2, 0x3e, 0x88, | ||||
| 0x7e, 0xae, 0xd1, 0xf3, 0x78, 0xe8, 0x05, 0xd1, 0xe3, 0xdc, 0x21, 0xf6, 0xe1, 0x9a, 0xbd, | ||||
| 0x17, 0x0e, 0xd9, 0x46, 0x9b, 0x88, 0x03, 0xea, 0xf6, 0x66, 0xbe, 0x0e, 0x1b, 0x50, 0x49, | ||||
| 0x96, 0x40, 0x97, 0xf1, 0xf1, 0xe4, 0x80, 0xa6, 0x6e, 0xe8, 0x77, 0x34, 0xbf, 0x29, 0x40, | ||||
| 0x44, 0xc2, 0xff, 0x4e, 0x98, 0xd3, 0x9c, 0xa3, 0x32, 0x2b, 0x76, 0x51, 0x04, 0x09, 0xe7, | ||||
| 0xa9, 0xd1, 0xa6, 0x32, 0xb1, 0x23, 0x53, 0xe2, 0x47, 0xab, 0xd6, 0xf5, 0x69, 0x5c, 0x3e, | ||||
| 0x5f, 0xfa, 0xae, 0x45, 0x20, 0xe5, 0xd2, 0x44, 0xff, 0x39, 0x32, 0x6d, 0xfd, 0x27, 0x57, | ||||
| 0x5c, 0xfd, 0xf0, 0xde, 0xc1, 0xb5, 0x99, 0xe5, 0xf5, 0x1c, 0x77, 0x01, 0x75, 0xc5, 0x6d, | ||||
| 0x58, 0x92, 0xf2, 0xb2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7a, 0x30, 0xff, 0xb7, 0xf0, 0xef, | ||||
| 0x77, 0xc1, 0x8a, 0x5d, 0xdc, 0xc0, 0xd1, 0x29, 0x30, 0x1e, 0x77, 0x38, 0x7a, 0x94, 0xf1, | ||||
| 0xb8, 0x7a, 0x7e, 0xef, 0xa4, 0xd1, 0xac, 0x31, 0x4a, 0xf2, 0x5d, 0x64, 0x3d, 0xb2, 0xe2, | ||||
| 0xf0, 0x08, 0x99, 0xfc, 0x70, 0xee, 0x24, 0xa7, 0x7e, 0xee, 0x1e, 0x20, 0x69, 0x7d, 0x44, | ||||
| 0xbf, 0x87, 0x42, 0xdf, 0x88, 0x3b, 0x0c, 0xda, 0x42, 0xc9, 0x04, 0xf9, 0x45, 0x50, 0xfc, | ||||
| 0x83, 0x8f, 0x11, 0x6a, 0x72, 0xbc, 0x99, 0x95, 0xf0, 0xac, 0x3d, 0xa7, 0x3b, 0xcd, 0x1c, | ||||
| 0xe2, 0x88, 0x79, 0x37, 0x11, 0x5f, 0x39, 0x89, 0x95, 0x0a, 0x16, 0x84, 0x7a, 0xf6, 0x8a, | ||||
| 0xa4, 0x28, 0xe4, 0xed, 0x83, 0x80, 0x3b, 0xb1, 0x23, 0xa5, 0x03, 0x10, 0xf4, 0x66, 0xea, | ||||
| 0xbb, 0x0c, 0x0f, 0xc5, 0xec, 0x6c, 0x69, 0xc5, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0x99, | ||||
| 0x88, 0x76, 0x08, 0xa0, 0xa8, 0x95, 0x7c, 0xd8, 0x38, 0x6d, 0xcd, 0x59, 0x02, 0x51, 0x4b, | ||||
| 0xf1, 0xb5, 0x2b, 0x50, 0xe3, 0xb6, 0xbd, 0xd0, 0x72, 0xcf, 0x9e, 0xfd, 0x6e, 0xbb, 0x44, | ||||
| 0xc8, 0x24, 0x8a, 0x77, 0x18, 0x8a, 0x13, 0x06, 0xef, 0x97, 0x7d, 0xfa, 0x81, 0xf0, 0x31, | ||||
| 0xe6, 0xfa, 0x77, 0xed, 0x31, 0x06, 0x31, 0x5b, 0x54, 0x8a, 0x9f, 0x30, 0x68, 0xdb, 0xe2, | ||||
| 0x40, 0xf8, 0x4e, 0x73, 0xfa, 0xab, 0x74, 0x8b, 0x10, 0x58, 0x13, 0xdc, 0xd2, 0xe6, 0x78, | ||||
| 0xd1, 0x32, 0x2e, 0x8a, 0x9f, 0x2c, 0x58, 0x06, 0x48, 0x27, 0xc5, 0xa9, 0x5e, 0x81, 0x47, | ||||
| 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xa4, 0x3e, 0x88, 0x9c, 0xda, 0x33, 0x0a, 0xce, 0xbc, | ||||
| 0x8b, 0x8e, 0xcf, 0x9f, 0xd3, 0x71, 0x80, 0x43, 0xcf, 0x6b, 0xa9, 0x51, 0x83, 0x76, 0x30, | ||||
| 0x82, 0xc5, 0x6a, 0x85, 0x39, 0x11, 0x50, 0x1a, 0x82, 0xdc, 0x1e, 0x1c, 0xd5, 0x7d, 0xa9, | ||||
| 0x71, 0x99, 0x33, 0x47, 0x19, 0x97, 0xb3, 0x5a, 0xb1, 0xdf, 0xed, 0xa4, 0xf2, 0xe6, 0x26, | ||||
| 0x84, 0xa2, 0x28, 0x9a, 0x9e, 0xdf, 0xa6, 0x6a, 0xf4, 0xd6, 0xfc, 0x2e, 0x5b, 0x9d, 0x1a, | ||||
| 0x2a, 0x27, 0x68, 0xfb, 0xc1, 0x83, 0x21, 0x4b, 0x90, 0xe0, 0x36, 0xdd, 0x5b, 0x31, 0x42, | ||||
| 0x55, 0xa0, 0x13, 0xf7, 0xd0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xc5, 0xf3, 0x21, | ||||
| 0xf8, 0x37, 0x2f, 0x40, 0xf3, 0xd4, 0xaf, 0x16, 0x08, 0x36, 0x02, 0xfc, 0x77, 0xc5, 0x8b, | ||||
| 0x04, 0x90, 0x56, 0xb9, 0xc9, 0x67, 0x9a, 0x99, 0xe8, 0x00, 0xd3, 0x86, 0xff, 0x97, 0x2d, | ||||
| 0x08, 0xe9, 0xb7, 0xb3, 0x91, 0xbc, 0xdf, 0x45, 0xc6, 0xed, 0x0f, 0x8c, 0x4c, 0x1e, 0xe6, | ||||
| 0x5b, 0x6e, 0x38, 0x30, 0xe4, 0xaa, 0xe3, 0x95, 0xde, 0xb9, 0xe4, 0x9a, 0xf5, 0xb2, 0x55, | ||||
| 0x9a, 0x87, 0x9b, 0xf6, 0x6a, 0xb2, 0xf2, 0x77, 0x9a, 0x31, 0xf4, 0x7a, 0x31, 0xd1, 0x1d, | ||||
| 0x04, 0xc0, 0x7c, 0x32, 0xa2, 0x9e, 0x9a, 0xf5, 0x62, 0xf8, 0x27, 0x8d, 0xbf, 0x51, 0xff, | ||||
| 0xd3, 0xdf, 0x64, 0x37, 0x3f, 0x2a, 0x6f, 0x76, 0x3a, 0x7d, 0x77, 0x06, 0x9e, 0x77, 0x7f, | ||||
| 0x5e, 0xeb, 0x32, 0x51, 0xf9, 0x16, 0x66, 0x9a, 0x09, 0xf3, 0xb0, 0x08, 0xa4, 0x70, 0x96, | ||||
| 0x46, 0x30, 0xff, 0xda, 0x4f, 0xe9, 0x1b, 0xed, 0x8d, 0xf8, 0x74, 0x1f, 0x31, 0x92, 0xb3, | ||||
| 0x73, 0x17, 0x36, 0xdb, 0x91, 0x30, 0xd6, 0x88, 0x55, 0x6b, 0x34, 0x77, 0x87, 0x7a, 0xe7, | ||||
| 0xee, 0x06, 0xc6, 0x1c, 0x8c, 0x19, 0x0c, 0x48, 0x46, 0x23, 0x5e, 0x9c, 0x07, 0x5c, 0xbf, | ||||
| 0xb4, 0x7e, 0xd6, 0x4f, 0x74, 0x9c, 0xe2, 0xc5, 0x50, 0x8b, 0xc5, 0x8b, 0x15, 0x90, 0x60, | ||||
| 0x62, 0x57, 0x29, 0xd0, 0x13, 0x43, 0xa1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xc7, 0x4d, 0x19, | ||||
| 0x86, 0xcc, 0x2f, 0x2a, 0x75, 0x5a, 0xfc, 0xeb, 0x97, 0x2a, 0x70, 0xe3, 0x78, 0xd8, 0x91, | ||||
| 0xb0, 0x4f, 0x99, 0x07, 0xa3, 0x95, 0xea, 0x24, 0x21, 0xd5, 0xde, 0x51, 0x20, 0x93, 0x27, | ||||
| 0x0a, 0x30, 0x73, 0xa8, 0xff, 0x8a, 0x97, 0xe9, 0xa7, 0x6a, 0x8e, 0x0d, 0xe8, 0xf0, 0xdf, | ||||
| 0xec, 0xea, 0xb4, 0x6c, 0x1d, 0x39, 0x2a, 0x62, 0x2d, 0x3d, 0x5a, 0x8b, 0x65, 0xf8, 0x90, | ||||
| 0x05, 0x2e, 0x7e, 0x91, 0x2c, 0x78, 0xef, 0x8e, 0x7a, 0xc1, 0x2f, 0xac, 0x78, 0xee, 0xaf, | ||||
| 0x28, 0x45, 0x06, 0x4c, 0x26, 0xaf, 0x3b, 0xa2, 0xdb, 0xa3, 0x93, 0x06, 0xb5, 0x3c, 0xa5, | ||||
| 0xd8, 0xee, 0x8f, 0xaf, 0x25, 0xcc, 0x3f, 0x85, 0x68, 0x48, 0xa9, 0x62, 0xcc, 0x97, 0x8f, | ||||
| 0x7f, 0x2a, 0xea, 0xe0, 0x15, 0x0a, 0xad, 0x62, 0x07, 0xbd, 0x45, 0xf8, 0x41, 0xd8, 0x36, | ||||
| 0xcb, 0x4c, 0xdb, 0x6e, 0xe6, 0x3a, 0xe7, 0xda, 0x15, 0xe9, 0x29, 0x1e, 0x12, 0x10, 0xa0, | ||||
| 0x14, 0x2c, 0x0e, 0x3d, 0xf4, 0xbf, 0x39, 0x41, 0x92, 0x75, 0x0b, 0x25, 0x7b, 0xa3, 0xce, | ||||
| 0x39, 0x9c, 0x15, 0x64, 0xc8, 0xfa, 0x3d, 0xef, 0x73, 0x27, 0xfe, 0x26, 0x2e, 0xce, 0xda, | ||||
| 0x6e, 0xfd, 0x71, 0x8e, 0xdd, 0xfe, 0x76, 0xee, 0xdc, 0x12, 0x5c, 0x02, 0xc5, 0x3a, 0x4e, | ||||
| 0x4e, 0x4f, 0xbf, 0xca, 0x40, 0x15, 0xc7, 0x6e, 0x8d, 0x41, 0xf1, 0x10, 0xe0, 0x4f, 0x7e, | ||||
| 0x97, 0x7f, 0x1c, 0xae, 0x47, 0x8e, 0x6b, 0xb1, 0x25, 0x31, 0xb0, 0x73, 0xc7, 0x1b, 0x97, | ||||
| 0x79, 0xf9, 0x80, 0xd3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1e, 0xe4, 0xd0, 0x80, 0x21, 0xd6, | ||||
| 0xee, 0x6b, 0x6c, 0x4f, 0xbf, 0xf5, 0xb7, 0xd9, 0x09, 0x87, 0x2f, 0xa9, 0x14, 0xbe, 0x27, | ||||
| 0xd9, 0x72, 0x50, 0x01, 0xd4, 0x13, 0x73, 0xa6, 0xa7, 0x51, 0x02, 0x75, 0x25, 0xe1, 0xb3, | ||||
| 0x45, 0x34, 0x7d, 0xa8, 0x8e, 0xeb, 0xf3, 0x16, 0x49, 0xcb, 0x4f, 0x8c, 0xa1, 0xb9, 0x36, | ||||
| 0x85, 0x39, 0x75, 0x5d, 0x08, 0x00, 0xae, 0xeb, 0xf6, 0xea, 0xd7, 0x13, 0x3a, 0x21, 0x5a, | ||||
| 0x5f, 0x30, 0x84, 0x52, 0x26, 0x95, 0xc9, 0x14, 0xf2, 0x57, 0x55, 0x6b, 0xb1, 0x10, 0xc2, | ||||
| 0xe1, 0xbd, 0x3b, 0x51, 0xc0, 0xb7, 0x55, 0x4c, 0x71, 0x12, 0x26, 0xc7, 0x0d, 0xf9, 0x51, | ||||
| 0xa4, 0x38, 0x02, 0x05, 0x7f, 0xb8, 0xf1, 0x72, 0x4b, 0xbf, 0x71, 0x89, 0x14, 0xf3, 0x77, | ||||
| 0x38, 0xd9, 0x71, 0x24, 0xf3, 0x00, 0x11, 0xa1, 0xd8, 0xd4, 0x69, 0x27, 0x08, 0x37, 0x35, | ||||
| 0xc9, 0x11, 0x9d, 0x90, 0x1c, 0x0e, 0xe7, 0x1c, 0xff, 0x2d, 0x1e, 0xe8, 0x92, 0xe1, 0x18, | ||||
| 0x10, 0x95, 0x7c, 0xe0, 0x80, 0xf4, 0x96, 0x43, 0x21, 0xf9, 0x75, 0x21, 0x64, 0x38, 0xdd, | ||||
| 0x9f, 0x1e, 0x95, 0x16, 0xda, 0x56, 0x1d, 0x4f, 0x9a, 0x53, 0xb2, 0xe2, 0xe4, 0x18, 0xcb, | ||||
| 0x6b, 0x1a, 0x65, 0xeb, 0x56, 0xc6, 0x3b, 0xe5, 0xfe, 0xd8, 0x26, 0x3f, 0x3a, 0x84, 0x59, | ||||
| 0x72, 0x66, 0xa2, 0xf3, 0x75, 0xff, 0xfb, 0x60, 0xb3, 0x22, 0xad, 0x3f, 0x2d, 0x6b, 0xf9, | ||||
| 0xeb, 0xea, 0x05, 0x7c, 0xd8, 0x8f, 0x6d, 0x2c, 0x98, 0x9e, 0x2b, 0x93, 0xf1, 0x5e, 0x46, | ||||
| 0xf0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xd7, 0x7f, 0xf9, 0xf0, 0xe5, 0x7d, 0xdb, 0x1d, 0x75, | ||||
| 0x19, 0xf3, 0xc4, 0x58, 0x9b, 0x17, 0x88, 0xa8, 0x92, 0xe0, 0xbe, 0xbd, 0x8b, 0x1d, 0x8d, | ||||
| 0x9f, 0x56, 0x76, 0xad, 0xaf, 0x29, 0xe2, 0xd9, 0xd5, 0x52, 0xf6, 0xb5, 0x56, 0x35, 0x57, | ||||
| 0x3a, 0xc8, 0xe1, 0x56, 0x43, 0x19, 0x94, 0xd3, 0x04, 0x9b, 0x6d, 0x35, 0xd8, 0x0b, 0x5f, | ||||
| 0x4d, 0x19, 0x8e, 0xec, 0xfa, 0x64, 0x91, 0x0a, 0x72, 0x20, 0x2b, 0xbc, 0x1a, 0x4a, 0xfe, | ||||
| 0x8b, 0xfd, 0xbb, 0xed, 0x1b, 0x23, 0xea, 0xad, 0x72, 0x82, 0xa1, 0x29, 0x99, 0x71, 0xbd, | ||||
| 0xf0, 0x95, 0xc1, 0x03, 0xdd, 0x7b, 0xc2, 0xb2, 0x3c, 0x28, 0x54, 0xd3, 0x68, 0xa4, 0x72, | ||||
| 0xc8, 0x66, 0x96, 0xe0, 0xd1, 0xd8, 0x7f, 0xf8, 0xd1, 0x26, 0x2b, 0xf7, 0xad, 0xba, 0x55, | ||||
| 0xca, 0x15, 0xb9, 0x32, 0xc3, 0xe5, 0x88, 0x97, 0x8e, 0x5c, 0xfb, 0x92, 0x25, 0x8b, 0xbf, | ||||
| 0xa2, 0x45, 0x55, 0x7a, 0xa7, 0x6f, 0x8b, 0x57, 0x5b, 0xcf, 0x0e, 0xcb, 0x1d, 0xfb, 0x20, | ||||
| 0x82, 0x77, 0xa8, 0x8c, 0xcc, 0x16, 0xce, 0x1d, 0xfa, 0xde, 0xcc, 0x0b, 0x62, 0xfe, 0xcc, | ||||
| 0xe1, 0xb7, 0xf0, 0xc3, 0x81, 0x64, 0x73, 0x40, 0xa0, 0xc2, 0x4d, 0x89, 0x11, 0x75, 0x33, | ||||
| 0x55, 0x33, 0x8d, 0xe8, 0x4a, 0xfd, 0xea, 0x6e, 0x30, 0x0b, 0xd7, 0x31, 0x2c, 0xde, 0x47, | ||||
| 0xe3, 0xbf, 0xf8, 0x55, 0x42, 0xe2, 0x7f, 0x59, 0xe5, 0x17, 0xef, 0x99, 0x34, 0x69, 0x91, | ||||
| 0xb1, 0x23, 0x8e, 0x20, 0x87, 0x2d, 0xa8, 0xfe, 0xd5, 0x8a, 0xf3, 0x84, 0x3a, 0xf0, 0x37, | ||||
| 0xe4, 0x09, 0x00, 0x54, 0xee, 0x67, 0x49, 0x93, 0xe4, 0x81, 0x70, 0xe3, 0x90, 0x4d, 0xef, | ||||
| 0xfe, 0x41, 0xb7, 0x99, 0x7b, 0xc1, 0x83, 0xba, 0x62, 0x12, 0x6f, 0x7d, 0xde, 0x6b, 0xaf, | ||||
| 0xda, 0x16, 0xf9, 0x55, 0x51, 0xee, 0xa6, 0x0c, 0x2b, 0x02, 0xa3, 0xfd, 0x8d, 0xfb, 0x30, | ||||
| 0x17, 0xe4, 0x6f, 0xdf, 0x36, 0x71, 0xc4, 0xca, 0x87, 0x25, 0x48, 0xb0, 0x47, 0xec, 0xea, | ||||
| 0xb4, 0xbf, 0xa5, 0x4d, 0x9b, 0x9f, 0x02, 0x93, 0xc4, 0xe3, 0xe4, 0xe8, 0x42, 0x2d, 0x68, | ||||
| 0x81, 0x15, 0x0a, 0xeb, 0x84, 0x5b, 0xd6, 0xa8, 0x74, 0xfb, 0x7d, 0x1d, 0xcb, 0x2c, 0xda, | ||||
| 0x46, 0x2a, 0x76, 0x62, 0xce, 0xbc, 0x5c, 0x9e, 0x8b, 0xe7, 0xcf, 0xbe, 0x78, 0xf5, 0x7c, | ||||
| 0xeb, 0xb3, 0x3a, 0x9c, 0xaa, 0x6f, 0xcc, 0x72, 0xd1, 0x59, 0xf2, 0x11, 0x23, 0xd6, 0x3f, | ||||
| 0x48, 0xd1, 0xb7, 0xce, 0xb0, 0xbf, 0xcb, 0xea, 0x80, 0xde, 0x57, 0xd4, 0x5e, 0x97, 0x2f, | ||||
| 0x75, 0xd1, 0x50, 0x8e, 0x80, 0x2c, 0x66, 0x79, 0xbf, 0x72, 0x4b, 0xbd, 0x8a, 0x81, 0x6c, | ||||
| 0xd3, 0xe1, 0x01, 0xdc, 0xd2, 0x15, 0x26, 0xc5, 0x36, 0xda, 0x2c, 0x1a, 0xc0, 0x27, 0x94, | ||||
| 0xed, 0xb7, 0x9b, 0x85, 0x0b, 0x5e, 0x80, 0x97, 0xc5, 0xec, 0x4f, 0xec, 0x88, 0x5d, 0x50, | ||||
| 0x07, 0x35, 0x47, 0xdc, 0x0b, 0x3b, 0x3d, 0xdd, 0x60, 0xaf, 0xa8, 0x5d, 0x81, 0x38, 0x24, | ||||
| 0x25, 0x5d, 0x5c, 0x15, 0xd1, 0xde, 0xb3, 0xab, 0xec, 0x05, 0x69, 0xef, 0x83, 0xed, 0x57, | ||||
| 0x54, 0xb8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xda, 0x9f, 0x2d, 0x7f, 0x36, 0xbb, 0x44, | ||||
| 0x5a, 0x34, 0xe8, 0x7f, 0xbf, 0x03, 0xeb, 0x00, 0x7f, 0x59, 0x68, 0x22, 0x79, 0xcf, 0x73, | ||||
| 0x6c, 0x2c, 0x29, 0xa7, 0xa1, 0x5f, 0x38, 0xa1, 0x1d, 0xf0, 0x20, 0x53, 0xe0, 0x1a, 0x63, | ||||
| 0x14, 0x58, 0x71, 0x10, 0xaa, 0x08, 0x0c, 0x3e, 0x16, 0x1a, 0x60, 0x22, 0x82, 0x7f, 0xba, | ||||
| 0xa4, 0x43, 0xa0, 0xd0, 0xac, 0x1b, 0xd5, 0x6b, 0x64, 0xb5, 0x14, 0x93, 0x31, 0x9e, 0x53, | ||||
| 0x50, 0xd0, 0x57, 0x66, 0xee, 0x5a, 0x4f, 0xfb, 0x03, 0x2a, 0x69, 0x58, 0x76, 0xf1, 0x83, | ||||
| 0xf7, 0x4e, 0xba, 0x8c, 0x42, 0x06, 0x60, 0x5d, 0x6d, 0xce, 0x60, 0x88, 0xae, 0xa4, 0xc3, | ||||
| 0xf1, 0x03, 0xa5, 0x4b, 0x98, 0xa1, 0xff, 0x67, 0xe1, 0xac, 0xa2, 0xb8, 0x62, 0xd7, 0x6f, | ||||
| 0xa0, 0x31, 0xb4, 0xd2, 0x77, 0xaf, 0x21, 0x10, 0x06, 0xc6, 0x9a, 0xff, 0x1d, 0x09, 0x17, | ||||
| 0x0e, 0x5f, 0xf1, 0xaa, 0x54, 0x34, 0x4b, 0x45, 0x8a, 0x87, 0x63, 0xa6, 0xdc, 0xf9, 0x24, | ||||
| 0x30, 0x67, 0xc6, 0xb2, 0xd6, 0x61, 0x33, 0x69, 0xee, 0x50, 0x61, 0x57, 0x28, 0xe7, 0x7e, | ||||
| 0xee, 0xec, 0x3a, 0x5a, 0x73, 0x4e, 0xa8, 0x8d, 0xe4, 0x18, 0xea, 0xec, 0x41, 0x64, 0xc8, | ||||
| 0xe2, 0xe8, 0x66, 0xb6, 0x2d, 0xb6, 0xfb, 0x6a, 0x6c, 0x16, 0xb3, 0xdd, 0x46, 0x43, 0xb9, | ||||
| 0x73, 0x00, 0x6a, 0x71, 0xed, 0x4e, 0x9d, 0x25, 0x1a, 0xc3, 0x3c, 0x4a, 0x95, 0x15, 0x99, | ||||
| 0x35, 0x81, 0x14, 0x02, 0xd6, 0x98, 0x9b, 0xec, 0xd8, 0x23, 0x3b, 0x84, 0x29, 0xaf, 0x0c, | ||||
| 0x99, 0x83, 0xa6, 0x9a, 0x34, 0x4f, 0xfa, 0xe8, 0xd0, 0x3c, 0x4b, 0xd0, 0xfb, 0xb6, 0x68, | ||||
| 0xb8, 0x9e, 0x8f, 0xcd, 0xf7, 0x60, 0x2d, 0x7a, 0x22, 0xe5, 0x7d, 0xab, 0x65, 0x1b, 0x95, | ||||
| 0xa7, 0xa8, 0x7f, 0xb6, 0x77, 0x47, 0x7b, 0x5f, 0x8b, 0x12, 0x72, 0xd0, 0xd4, 0x91, 0xef, | ||||
| 0xde, 0x19, 0x50, 0x3c, 0xa7, 0x8b, 0xc4, 0xa9, 0xb3, 0x23, 0xcb, 0x76, 0xe6, 0x81, 0xf0, | ||||
| 0xc1, 0x04, 0x8f, 0xa3, 0xb8, 0x54, 0x5b, 0x97, 0xac, 0x19, 0xff, 0x3f, 0x55, 0x27, 0x2f, | ||||
| 0xe0, 0x1d, 0x42, 0x9b, 0x57, 0xfc, 0x4b, 0x4e, 0x0f, 0xce, 0x98, 0xa9, 0x43, 0x57, 0x03, | ||||
| 0xbd, 0xe7, 0xc8, 0x94, 0xdf, 0x6e, 0x36, 0x73, 0x32, 0xb4, 0xef, 0x2e, 0x85, 0x7a, 0x6e, | ||||
| 0xfc, 0x6c, 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xf3, 0xe4, 0x9f, 0x3e, 0xdc, 0x68, 0xf3, | ||||
| 0xb5, 0xf3, 0x19, 0x80, 0x92, 0x06, 0x99, 0xa2, 0xe8, 0x6f, 0xff, 0x2e, 0x7f, 0xae, 0x42, | ||||
| 0xa4, 0x5f, 0xfb, 0xd4, 0x0e, 0x81, 0x2b, 0xc3, 0x04, 0xff, 0x2b, 0xb3, 0x74, 0x4e, 0x36, | ||||
| 0x5b, 0x9c, 0x15, 0x00, 0xc6, 0x47, 0x2b, 0xe8, 0x8b, 0x3d, 0xf1, 0x9c, 0x03, 0x9a, 0x58, | ||||
| 0x7f, 0x9b, 0x9c, 0xbf, 0x85, 0x49, 0x79, 0x35, 0x2e, 0x56, 0x7b, 0x41, 0x14, 0x39, 0x47, | ||||
| 0x83, 0x26, 0xaa, 0x07, 0x89, 0x98, 0x11, 0x1b, 0x86, 0xe7, 0x73, 0x7a, 0xd8, 0x7d, 0x78, | ||||
| 0x61, 0x53, 0xe9, 0x79, 0xf5, 0x36, 0x8d, 0x44, 0x92, 0x84, 0xf9, 0x13, 0x50, 0x58, 0x3b, | ||||
| 0xa4, 0x6a, 0x36, 0x65, 0x49, 0x8e, 0x3c, 0x0e, 0xf1, 0x6f, 0xd2, 0x84, 0xc4, 0x7e, 0x8e, | ||||
| 0x3f, 0x39, 0xae, 0x7c, 0x84, 0xf1, 0x63, 0x37, 0x8e, 0x3c, 0xcc, 0x3e, 0x44, 0x81, 0x45, | ||||
| 0xf1, 0x4b, 0xb9, 0xed, 0x6b, 0x36, 0x5d, 0xbb, 0x20, 0x60, 0x1a, 0x0f, 0xa3, 0xaa, 0x55, | ||||
| 0x77, 0x3a, 0xa9, 0xae, 0x37, 0x4d, 0xba, 0xb8, 0x86, 0x6b, 0xbc, 0x08, 0x50, 0xf6, 0xcc, | ||||
| 0xa4, 0xbd, 0x1d, 0x40, 0x72, 0xa5, 0x86, 0xfa, 0xe2, 0x10, 0xae, 0x3d, 0x58, 0x4b, 0x97, | ||||
| 0xf3, 0x43, 0x74, 0xa9, 0x9e, 0xeb, 0x21, 0xb7, 0x01, 0xa4, 0x86, 0x93, 0x97, 0xee, 0x2f, | ||||
| 0x4f, 0x3b, 0x86, 0xa1, 0x41, 0x6f, 0x41, 0x26, 0x90, 0x78, 0x5c, 0x7f, 0x30, 0x38, 0x4b, | ||||
| 0x3f, 0xaa, 0xec, 0xed, 0x5c, 0x6f, 0x0e, 0xad, 0x43, 0x87, 0xfd, 0x93, 0x35, 0xe6, 0x01, | ||||
| 0xef, 0x41, 0x26, 0x90, 0x99, 0x9e, 0xfb, 0x19, 0x5b, 0xad, 0xd2, 0x91, 0x8a, 0xe0, 0x46, | ||||
| 0xaf, 0x65, 0xfa, 0x4f, 0x84, 0xc1, 0xa1, 0x2d, 0xcf, 0x45, 0x8b, 0xd3, 0x85, 0x50, 0x55, | ||||
| 0x7c, 0xf9, 0x67, 0x88, 0xd4, 0x4e, 0xe9, 0xd7, 0x6b, 0x61, 0x54, 0xa1, 0xa4, 0xa6, 0xa2, | ||||
| 0xc2, 0xbf, 0x30, 0x9c, 0x40, 0x9f, 0x5f, 0xd7, 0x69, 0x2b, 0x24, 0x82, 0x5e, 0xd9, 0xd6, | ||||
| 0xa7, 0x12, 0x54, 0x1a, 0xf7, 0x55, 0x9f, 0x76, 0x50, 0xa9, 0x95, 0x84, 0xe6, 0x6b, 0x6d, | ||||
| 0xb5, 0x96, 0x54, 0xd6, 0xcd, 0xb3, 0xa1, 0x9b, 0x46, 0xa7, 0x94, 0x4d, 0xc4, 0x94, 0xb4, | ||||
| 0x98, 0xe3, 0xe1, 0xe2, 0x34, 0xd5, 0x33, 0x16, 0x07, 0x54, 0xcd, 0xb7, 0x77, 0x53, 0xdb, | ||||
| 0x4f, 0x4d, 0x46, 0x9d, 0xe9, 0xd4, 0x9c, 0x8a, 0x36, 0xb6, 0xb8, 0x38, 0x26, 0x6c, 0x0e, | ||||
| 0xff, 0x9c, 0x1b, 0x43, 0x8b, 0x80, 0xcc, 0xb9, 0x3d, 0xda, 0xc7, 0xf1, 0x8a, 0xf2, 0x6d, | ||||
| 0xb8, 0xd7, 0x74, 0x2f, 0x7e, 0x1e, 0xb7, 0xd3, 0x4a, 0xb4, 0xac, 0xfc, 0x79, 0x48, 0x6c, | ||||
| 0xbc, 0x96, 0xb6, 0x94, 0x46, 0x57, 0x2d, 0xb0, 0xa3, 0xfc, 0x1e, 0xb9, 0x52, 0x60, 0x85, | ||||
| 0x2d, 0x41, 0xd0, 0x43, 0x01, 0x1e, 0x1c, 0xd5, 0x7d, 0xfc, 0xf3, 0x96, 0x0d, 0xc7, 0xcb, | ||||
| 0x2a, 0x29, 0x9a, 0x93, 0xdd, 0x88, 0x2d, 0x37, 0x5d, 0xaa, 0xfb, 0x49, 0x68, 0xa0, 0x9c, | ||||
| 0x50, 0x86, 0x7f, 0x68, 0x56, 0x57, 0xf9, 0x79, 0x18, 0x39, 0xd4, 0xe0, 0x01, 0x84, 0x33, | ||||
| 0x61, 0xca, 0xa5, 0xd2, 0xd6, 0xe4, 0xc9, 0x8a, 0x4a, 0x23, 0x44, 0x4e, 0xbc, 0xf0, 0xdc, | ||||
| 0x24, 0xa1, 0xa0, 0xc4, 0xe2, 0x07, 0x3c, 0x10, 0xc4, 0xb5, 0x25, 0x4b, 0x65, 0x63, 0xf4, | ||||
| 0x80, 0xe7, 0xcf, 0x61, 0xb1, 0x71, 0x82, 0x21, 0x87, 0x2c, 0xf5, 0x91, 0x00, 0x32, 0x0c, | ||||
| 0xec, 0xa9, 0xb5, 0x9a, 0x74, 0x85, 0xe3, 0x36, 0x8f, 0x76, 0x4f, 0x9c, 0x6d, 0xce, 0xbc, | ||||
| 0xad, 0x0a, 0x4b, 0xed, 0x76, 0x04, 0xcb, 0xc3, 0xb9, 0x33, 0x9e, 0x01, 0x93, 0x96, 0x69, | ||||
| 0x7d, 0xc5, 0xa2, 0x45, 0x79, 0x9b, 0x04, 0x5c, 0x84, 0x09, 0xed, 0x88, 0x43, 0xc7, 0xab, | ||||
| 0x93, 0x14, 0x26, 0xa1, 0x40, 0xb5, 0xce, 0x4e, 0xbf, 0x2a, 0x42, 0x85, 0x3e, 0x2c, 0x3b, | ||||
| 0x54, 0xe8, 0x12, 0x1f, 0x0e, 0x97, 0x59, 0xb2, 0x27, 0x89, 0xfa, 0xf2, 0xdf, 0x8e, 0x68, | ||||
| 0x59, 0xdc, 0x06, 0xbc, 0xb6, 0x85, 0x0d, 0x06, 0x22, 0xec, 0xb1, 0xcb, 0xe5, 0x04, 0xe6, | ||||
| 0x3d, 0xb3, 0xb0, 0x41, 0x73, 0x08, 0x3f, 0x3c, 0x58, 0x86, 0x63, 0xeb, 0x50, 0xee, 0x1d, | ||||
| 0x2c, 0x37, 0x74, 0xa9, 0xd3, 0x18, 0xa3, 0x47, 0x6e, 0x93, 0x54, 0xad, 0x0a, 0x5d, 0xb8, | ||||
| 0x2a, 0x55, 0x5d, 0x78, 0xf6, 0xee, 0xbe, 0x8e, 0x3c, 0x76, 0x69, 0xb9, 0x40, 0xc2, 0x34, | ||||
| 0xec, 0x2a, 0xb9, 0xed, 0x7e, 0x20, 0xe4, 0x8d, 0x00, 0x38, 0xc7, 0xe6, 0x8f, 0x44, 0xa8, | ||||
| 0x86, 0xce, 0xeb, 0x2a, 0xe9, 0x90, 0xf1, 0x4c, 0xdf, 0x32, 0xfb, 0x73, 0x1b, 0x6d, 0x92, | ||||
| 0x1e, 0x95, 0xfe, 0xb4, 0xdb, 0x65, 0xdf, 0x4d, 0x23, 0x54, 0x89, 0x48, 0xbf, 0x4a, 0x2e, | ||||
| 0x70, 0xd6, 0xd7, 0x62, 0xb4, 0x33, 0x29, 0xb1, 0x3a, 0x33, 0x4c, 0x23, 0x6d, 0xa6, 0x76, | ||||
| 0xa5, 0x21, 0x63, 0x48, 0xe6, 0x90, 0x5d, 0xed, 0x90, 0x95, 0x0b, 0x7a, 0x84, 0xbe, 0xb8, | ||||
| 0x0d, 0x5e, 0x63, 0x0c, 0x62, 0x26, 0x4c, 0x14, 0x5a, 0xb3, 0xac, 0x23, 0xa4, 0x74, 0xa7, | ||||
| 0x6f, 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xa0, 0x28, 0xb7, 0xee, 0x19, 0x38, 0xf1, 0x64, | ||||
| 0x80, 0x82, 0x43, 0xe1, 0x41, 0x27, 0x1f, 0x1f, 0x90, 0x54, 0x7a, 0xd5, 0x23, 0x2e, 0xd1, | ||||
| 0x3d, 0xcb, 0x28, 0xba, 0x58, 0x7f, 0xdc, 0x7c, 0x91, 0x24, 0xe9, 0x28, 0x51, 0x83, 0x6e, | ||||
| 0xc5, 0x56, 0x21, 0x42, 0xed, 0xa0, 0x56, 0x22, 0xa1, 0x40, 0x80, 0x6b, 0xa8, 0xf7, 0x94, | ||||
| 0xca, 0x13, 0x6b, 0x0c, 0x39, 0xd9, 0xfd, 0xe9, 0xf3, 0x6f, 0xa6, 0x9e, 0xfc, 0x70, 0x8a, | ||||
| 0xb3, 0xbc, 0x59, 0x3c, 0x1e, 0x1d, 0x6c, 0xf9, 0x7c, 0xaf, 0xf9, 0x88, 0x71, 0x95, 0xeb, | ||||
| 0x57, 0x00, 0xbd, 0x9f, 0x8c, 0x4f, 0xe1, 0x24, 0x83, 0xc5, 0x22, 0xea, 0xfd, 0xd3, 0x0c, | ||||
| 0xe2, 0x17, 0x18, 0x7c, 0x6a, 0x4c, 0xde, 0x77, 0xb4, 0x53, 0x9b, 0x4c, 0x81, 0xcd, 0x23, | ||||
| 0x60, 0xaa, 0x0e, 0x25, 0x73, 0x9c, 0x02, 0x79, 0x32, 0x30, 0xdf, 0x74, 0xdf, 0x75, 0x19, | ||||
| 0xf4, 0xa5, 0x14, 0x5c, 0xf7, 0x7a, 0xa8, 0xa5, 0x91, 0x84, 0x7c, 0x60, 0x03, 0x06, 0x3b, | ||||
| 0xcd, 0x50, 0xb6, 0x27, 0x9c, 0xfe, 0xb1, 0xdd, 0xcc, 0xd3, 0xb0, 0x59, 0x24, 0xb2, 0xca, | ||||
| 0xe2, 0x1c, 0x81, 0x22, 0x9d, 0x07, 0x8f, 0x8e, 0xb9, 0xbe, 0x4e, 0xfa, 0xfc, 0x39, 0x65, | ||||
| 0xba, 0xbf, 0x9d, 0x12, 0x37, 0x5e, 0x97, 0x7e, 0xf3, 0x89, 0xf5, 0x5d, 0xf5, 0xe3, 0x09, | ||||
| 0x8c, 0x62, 0xb5, 0x20, 0x9d, 0x0c, 0x53, 0x8a, 0x68, 0x1b, 0xd2, 0x8f, 0x75, 0x17, 0x5d, | ||||
| 0xd4, 0xe5, 0xda, 0x75, 0x62, 0x19, 0x14, 0x6a, 0x26, 0x2d, 0xeb, 0xf8, 0xaf, 0x37, 0xf0, | ||||
| 0x6c, 0xa4, 0x55, 0xb1, 0xbc, 0xe2, 0x33, 0xc0, 0x9a, 0xca, 0xb0, 0x11, 0x49, 0x4f, 0x68, | ||||
| 0x9b, 0x3b, 0x6b, 0x3c, 0xcc, 0x13, 0xf6, 0xc7, 0x85, 0x61, 0x68, 0x42, 0xae, 0xbb, 0xdd, | ||||
| 0xcd, 0x45, 0x16, 0x29, 0x1d, 0xea, 0xdb, 0xc8, 0x03, 0x94, 0x3c, 0xee, 0x4f, 0x82, 0x11, | ||||
| 0xc3, 0xec, 0x28, 0xbd, 0x97, 0x05, 0x99, 0xde, 0xd7, 0xbb, 0x5e, 0x22, 0x1f, 0xd4, 0xeb, | ||||
| 0x64, 0xd9, 0x92, 0xd9, 0x85, 0xb7, 0x6a, 0x05, 0x6a, 0xe4, 0x24, 0x41, 0xf1, 0xcd, 0xf0, | ||||
| 0xd8, 0x3f, 0xf8, 0x9e, 0x0e, 0xcd, 0x0b, 0x7a, 0x70, 0x6b, 0x5a, 0x75, 0x0a, 0x6a, 0x33, | ||||
| 0x88, 0xec, 0x17, 0x75, 0x08, 0x70, 0x10, 0x2f, 0x24, 0xcf, 0xc4, 0xe9, 0x42, 0x00, 0x61, | ||||
| 0x94, 0xca, 0x1f, 0x3a, 0x76, 0x06, 0xfa, 0xd2, 0x48, 0x81, 0xf0, 0x77, 0x60, 0x03, 0x45, | ||||
| 0xd9, 0x61, 0xf4, 0xa4, 0x6f, 0x3d, 0xd9, 0x30, 0xc3, 0x04, 0x6b, 0x54, 0x2a, 0xb7, 0xec, | ||||
| 0x3b, 0xf4, 0x4b, 0xf5, 0x68, 0x52, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5, | ||||
| 0xa9, 0xb1, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xa5, 0xa9, 0xb1, | ||||
| 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0xeb, 0x54, 0x0b, | ||||
| 0x75, 0x68, 0x52, 0x07, 0x8c, 0x9a, 0x97, 0x8d, 0x79, 0x70, 0x62, 0x46, 0xef, 0x5c, 0x1b, | ||||
| 0x95, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x67, 0x4c, 0x1a, 0xb6, | ||||
| 0xcf, 0xfd, 0x78, 0x53, 0x24, 0xab, 0xb5, 0xc9, 0xf1, 0x60, 0x23, 0xa5, 0xc8, 0x12, 0x87, | ||||
| 0x6d, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xc7, 0x0c, 0x9a, 0x97, 0xac, | ||||
| 0xda, 0x36, 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x47, | ||||
| 0xed, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8c, 0x7b, 0x55, 0x09, 0x90, 0xa2, 0xc6, 0xef, | ||||
| 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xdf, | ||||
| 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x59, 0x30, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x53, 0x05, 0x69, | ||||
| 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0xb0, 0xe2, 0x27, 0xcc, 0xfb, 0x74, | ||||
| 0x4b, 0x14, 0x8b, 0x94, 0x8b, 0x75, 0x68, 0x33, 0xc5, 0x08, 0x92, 0x87, 0x8c, 0x9a, 0xb6, | ||||
| 0xcf, 0x1c, 0xba, 0xd7, 0x0d, 0x98, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0x89, 0x71, 0x60, | ||||
| 0x23, 0xc4, 0x0a, 0x96, 0x8f, 0x9c, 0xba, 0xf6, 0x6e, 0x3f, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, | ||||
| 0x26, 0xaf, 0xbd, 0xf8, 0x72, 0x66, 0x2f, 0xdc, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa, | ||||
| 0xb7, 0xcd, 0xf9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6f, 0x3d, 0xd9, 0x30, 0xe2, 0x27, 0xcc, | ||||
| 0xfb, 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x70, 0x43, 0x04, 0x6b, 0x35, 0xc9, 0xf1, | ||||
| 0x60, 0x23, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xe6, 0x2f, 0xbd, | ||||
| 0xf8, 0x72, 0x66, 0x4e, 0x1e, 0xbe, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x1d, 0x99, 0x91, 0xa0, | ||||
| 0xa3, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93, 0xa4, 0xab, 0xd4, 0x0b, 0x75, 0x49, 0x10, 0xa2, | ||||
| 0xc6, 0xef, 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xb5, 0xe8, 0x33, 0xe4, 0x4a, 0x16, 0xae, 0xde, | ||||
| 0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xb3, 0xc5, 0x08, 0x73, 0x45, 0xe9, 0x31, 0xc1, 0xe1, 0x21, | ||||
| 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x86, 0x6f, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, 0x93, 0xa4, 0xca, | ||||
| 0x16, 0xae, 0xde, 0x1f, 0x9d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x72, 0x47, 0x0c, | ||||
| 0x9a, 0xb6, 0xcf, 0xfd, 0x59, 0x11, 0xa0, 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, | ||||
| 0x6d, 0x39, 0xf0, 0x43, 0x04, 0x8a, 0x96, 0xae, 0xde, 0x3e, 0xdf, 0x1d, 0x99, 0x91, 0xa0, | ||||
| 0xc2, 0x06, 0x6f, 0x3d, 0xf8, 0x72, 0x47, 0x0c, 0x9a, 0x97, 0x8d, 0x98, 0x93, 0x85, 0x88, | ||||
| 0x73, 0x45, 0xe9, 0x31, 0xe0, 0x23, 0xa5, 0xa9, 0xd0, 0x03, 0x84, 0x8a, 0x96, 0xae, 0xde, | ||||
| 0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xd2, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x82, | ||||
| 0x67, 0x2d, 0xd8, 0x13, 0xa4, 0xab, 0xd4, 0x0b, 0x94, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, | ||||
| 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0xe9, 0x50, 0x22, 0xc6, 0xef, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, | ||||
| 0x93, 0x85, 0x88, 0x73, 0x64, 0x4a, 0xf7, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0x0a, 0x96, | ||||
| 0xae, 0xde, 0x3e, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x78, 0x72, | ||||
| 0x66, 0x2f, 0xbd, 0xd9, 0x30, 0xc3, 0xe5, 0x48, 0x12, 0x87, 0x8c, 0x7b, 0x55, 0x28, 0xd2, | ||||
| 0x07, 0x8c, 0x9a, 0x97, 0xac, 0xda, 0x17, 0x8d, 0x79, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x54, | ||||
| 0x0b, 0x94, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, 0x26, 0xaf, | ||||
| 0xdc, 0x1b, 0xb4, 0xea, 0x37, 0xec, 0x3b, 0xf4, 0x6a, 0x37, 0xcd, 0x18, 0x93, 0x85, 0x69, | ||||
| 0x31, 0xc1, 0xe1, 0x40, 0xe3, 0x25, 0xc8, 0x12, 0x87, 0x8c, 0x9a, 0xb6, 0xcf, 0xfd, 0x59, | ||||
| 0x11, 0xa0, 0xc2, 0x06, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x37, | ||||
| 0xec, 0x5a, 0x36, 0xee, 0x3f, 0xfc, 0x7a, 0x76, 0x4f, 0x1c, 0x9b, 0x95, 0x89, 0x71, 0x41, | ||||
| 0x00, 0x63, 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x0f, 0x9c, 0xba, 0xd7, 0x0d, 0x98, 0x93, 0x85, | ||||
| 0x69, 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x9e, 0xbe, 0xdf, 0x3c, 0xfa, 0x57, 0x2c, 0xda, | ||||
| 0x36, 0xee, 0x3f, 0xfc, 0x5b, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, | ||||
| 0x38, 0xf2, 0x47, 0xed, 0x58, 0x13, 0xa4, 0xca, 0xf7, 0x4d, 0xf9, 0x51, 0x01, 0x80, 0x63, | ||||
| 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xa9, 0xb1, | ||||
| 0xe0, 0x42, 0x06, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0x0a, 0x96, 0x8f, 0x7d, | ||||
| 0x78, 0x72, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0xbc, 0xfa, 0x57, 0x0d, | ||||
| 0x79, 0x51, 0x01, 0x61, 0x21, 0xa1, 0xc0, 0xe3, 0x25, 0xa9, 0xb1, 0xc1, 0xe1, 0x40, 0x02, | ||||
| 0x67, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xd6, 0x0f, 0x9c, 0x9b, | ||||
| 0xb4, 0xcb, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x35, 0xc9, 0xf1, | ||||
| 0x60, 0x42, 0x06, 0x8e, 0x7f, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xfc, 0x7a, 0x76, 0x6e, 0x5e, | ||||
| 0x3e, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xc0, 0xe3, 0x44, | ||||
| 0xeb, 0x54, 0x2a, 0xb7, 0xcd, 0xf9, 0x70, 0x62, 0x27, 0xad, 0xd8, 0x32, 0xc7, 0x0c, 0x7b, | ||||
| 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x6d, 0x39, 0xd1, 0x20, | ||||
| 0xc2, 0xe7, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0xb2, 0xc7, 0x0c, 0x59, 0x28, 0xf3, 0x9b }; | ||||
| 
 | ||||
| // clang-format off
 | ||||
| @ -24,6 +24,6 @@ POINTING_DEVICE_ENABLE = yes | ||||
| MOUSEKEY_ENABLE = yes       # Mouse keys | ||||
| 
 | ||||
| QUANTUM_LIB_SRC += analog.c spi_master.c | ||||
| SRC += pmw3360.c opt_encoder.c | ||||
| SRC += drivers/sensors/pmw3360.c opt_encoder.c | ||||
| 
 | ||||
| DEFAULT_FOLDER = ploopyco/trackball/rev1_005 | ||||
|  | ||||
| @ -20,7 +20,7 @@ | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "spi_master.h" | ||||
| #include "pmw3360.h" | ||||
| #include "drivers/sensors/pmw3360.h" | ||||
| #include "analog.h" | ||||
| #include "opt_encoder.h" | ||||
| #include "pointing_device.h" | ||||
|  | ||||
| @ -27,6 +27,6 @@ POINTING_DEVICE_ENABLE = yes | ||||
| MOUSEKEY_ENABLE = no        # Mouse keys | ||||
| 
 | ||||
| QUANTUM_LIB_SRC += analog.c | ||||
| SRC += adns5050.c opt_encoder.c | ||||
| SRC += drivers/sensors/adns5050.c opt_encoder.c | ||||
| 
 | ||||
| DEFAULT_FOLDER = ploopyco/trackball_mini/rev1_001 | ||||
|  | ||||
| @ -20,7 +20,7 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "adns5050.h" | ||||
| #include "drivers/sensors/adns5050.h" | ||||
| #include "analog.h" | ||||
| #include "opt_encoder.h" | ||||
| #include "pointing_device.h" | ||||
|  | ||||
| @ -27,6 +27,6 @@ POINTING_DEVICE_ENABLE = yes | ||||
| MOUSEKEY_ENABLE = no        # Mouse keys | ||||
| 
 | ||||
| QUANTUM_LIB_SRC += analog.c | ||||
| SRC += adns5050.c opt_encoder.c | ||||
| SRC += drivers/sensors/adns5050.c opt_encoder.c | ||||
| 
 | ||||
| DEFAULT_FOLDER = ploopyco/trackball_nano/rev1_001 | ||||
|  | ||||
| @ -20,7 +20,7 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "adns5050.h" | ||||
| #include "drivers/sensors/adns5050.h" | ||||
| #include "analog.h" | ||||
| #include "opt_encoder.h" | ||||
| #include "pointing_device.h" | ||||
|  | ||||
| @ -47,3 +47,4 @@ | ||||
| 
 | ||||
| #define PIMORONI_TRACKBALL_INVERT_X | ||||
| #define PIMORONI_TRACKBALL_INVERT_Y | ||||
| #define PIMORONI_TRACKBALL_CLICK | ||||
|  | ||||
| @ -33,7 +33,7 @@ | ||||
| #    include "oled_stuff.h" | ||||
| #endif | ||||
| #if defined(PIMORONI_TRACKBALL_ENABLE) | ||||
| #    include "pimoroni_trackball.h" | ||||
| #    include "drivers/sensors/pimoroni_trackball.h" | ||||
| #endif | ||||
| 
 | ||||
| /* Define layer names */ | ||||
|  | ||||
| @ -1,151 +0,0 @@ | ||||
| /* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include "pimoroni_trackball.h" | ||||
| #include "i2c_master.h" | ||||
| 
 | ||||
| static uint8_t scrolling      = 0; | ||||
| static int16_t x_offset       = 0; | ||||
| static int16_t y_offset       = 0; | ||||
| static int16_t h_offset       = 0; | ||||
| static int16_t v_offset       = 0; | ||||
| static float   precisionSpeed = 1; | ||||
| 
 | ||||
| #ifndef I2C_TIMEOUT | ||||
| #    define I2C_TIMEOUT 100 | ||||
| #endif | ||||
| #ifndef MOUSE_DEBOUNCE | ||||
| #    define MOUSE_DEBOUNCE 5 | ||||
| #endif | ||||
| 
 | ||||
| void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { | ||||
|     uint8_t data[] = {0x00, red, green, blue, white}; | ||||
|     i2c_transmit(TRACKBALL_ADDRESS << 1, data, sizeof(data), I2C_TIMEOUT); | ||||
| } | ||||
| 
 | ||||
| int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) { | ||||
|     int16_t offset    = (int16_t)positive - (int16_t)negative; | ||||
|     int16_t magnitude = (int16_t)(scale * offset * offset * precisionSpeed); | ||||
|     return offset < 0 ? -magnitude : magnitude; | ||||
| } | ||||
| 
 | ||||
| void update_member(int8_t* member, int16_t* offset) { | ||||
|     if (*offset > 127) { | ||||
|         *member = 127; | ||||
|         *offset -= 127; | ||||
|     } else if (*offset < -127) { | ||||
|         *member = -127; | ||||
|         *offset += 127; | ||||
|     } else { | ||||
|         *member = *offset; | ||||
|         *offset = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| __attribute__((weak)) void trackball_check_click(bool pressed, report_mouse_t* mouse) { | ||||
|     if (pressed) { | ||||
|         mouse->buttons |= MOUSE_BTN1; | ||||
|     } else { | ||||
|         mouse->buttons &= ~MOUSE_BTN1; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void trackball_register_button(bool pressed, enum mouse_buttons button) { | ||||
|     report_mouse_t currentReport = pointing_device_get_report(); | ||||
|     if (pressed) { | ||||
|         currentReport.buttons |= button; | ||||
|     } else { | ||||
|         currentReport.buttons &= ~button; | ||||
|     } | ||||
|     pointing_device_set_report(currentReport); | ||||
| } | ||||
| 
 | ||||
| float trackball_get_precision(void) { return precisionSpeed; } | ||||
| void  trackball_set_precision(float precision) { precisionSpeed = precision; } | ||||
| bool  trackball_is_scrolling(void) { return scrolling; } | ||||
| void  trackball_set_scrolling(bool scroll) { scrolling = scroll; } | ||||
| 
 | ||||
| bool has_report_changed (report_mouse_t first, report_mouse_t second) { | ||||
|     return !( | ||||
|         (!first.buttons && first.buttons == second.buttons) && | ||||
|         (!first.x && first.x == second.x) && | ||||
|         (!first.y && first.y == second.y) && | ||||
|         (!first.h && first.h == second.h) && | ||||
|         (!first.v && first.v == second.v) ); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| __attribute__((weak)) void pointing_device_init(void) { trackball_set_rgbw(0x00, 0x00, 0x00, 0x4F); } | ||||
| 
 | ||||
| void pointing_device_task(void) { | ||||
|     static bool     debounce; | ||||
|     static uint16_t debounce_timer; | ||||
|     uint8_t         state[5] = {}; | ||||
|     if (i2c_readReg(TRACKBALL_ADDRESS << 1, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { | ||||
|         if (!state[4] && !debounce) { | ||||
|             if (scrolling) { | ||||
| #ifdef PIMORONI_TRACKBALL_INVERT_X | ||||
|                 h_offset += mouse_offset(state[2], state[3], 1); | ||||
| #else | ||||
|                 h_offset -= mouse_offset(state[2], state[3], 1); | ||||
| #endif | ||||
| #ifdef PIMORONI_TRACKBALL_INVERT_Y | ||||
|                 v_offset += mouse_offset(state[1], state[0], 1); | ||||
| #else | ||||
|                 v_offset -= mouse_offset(state[1], state[0], 1); | ||||
| #endif | ||||
|             } else { | ||||
| #ifdef PIMORONI_TRACKBALL_INVERT_X | ||||
|                 x_offset -= mouse_offset(state[2], state[3], 5); | ||||
| #else | ||||
|                 x_offset += mouse_offset(state[2], state[3], 5); | ||||
| #endif | ||||
| #ifdef PIMORONI_TRACKBALL_INVERT_Y | ||||
|                 y_offset -= mouse_offset(state[1], state[0], 5); | ||||
| #else | ||||
|                 y_offset += mouse_offset(state[1], state[0], 5); | ||||
| #endif | ||||
|             } | ||||
|         } else { | ||||
|             if (state[4]) { | ||||
|                 debounce       = true; | ||||
|                 debounce_timer = timer_read(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false; | ||||
| 
 | ||||
|     report_mouse_t mouse = pointing_device_get_report(); | ||||
| 
 | ||||
|     trackball_check_click(state[4] & (1 << 7), &mouse); | ||||
| 
 | ||||
| #ifndef PIMORONI_TRACKBALL_ROTATE | ||||
|     update_member(&mouse.x, &x_offset); | ||||
|     update_member(&mouse.y, &y_offset); | ||||
|     update_member(&mouse.h, &h_offset); | ||||
|     update_member(&mouse.v, &v_offset); | ||||
| #else | ||||
|     update_member(&mouse.x, &y_offset); | ||||
|     update_member(&mouse.y, &x_offset); | ||||
|     update_member(&mouse.h, &v_offset); | ||||
|     update_member(&mouse.v, &h_offset); | ||||
| #endif | ||||
|     pointing_device_set_report(mouse); | ||||
|     if (has_report_changed(mouse, pointing_device_get_report())) { | ||||
|         pointing_device_send(); | ||||
|     } | ||||
| } | ||||
| @ -74,7 +74,7 @@ endif | ||||
| ifeq ($(strip $(PIMORONI_TRACKBALL_ENABLE)), yes) | ||||
|     POINTING_DEVICE_ENABLE := yes | ||||
|     OPT_DEFS += -DPIMORONI_TRACKBALL_ENABLE | ||||
|     SRC += pimoroni_trackball.c | ||||
|     SRC += drivers/sensors/pimoroni_trackball.c | ||||
|     QUANTUM_LIB_SRC += i2c_master.c | ||||
| endif | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user