123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #include <stdbool.h>
- #include <stdint.h>
- #include "adns2080.h"
- #include "sdio.h"
- #define ADNS2080_PRODUCT_ID (0x2AU)
- #define ADNS2080_RESET_NUMBER (0x5AU)
- #define REG_PROD_ID (0x00U)
- #define REG_REV_ID (0x01U)
- #define REG_MOTION_ST (0x02U)
- #define REG_DELTA_X (0x03U)
- #define REG_DELTA_Y (0x04U)
- #define REG_SQUAL (0x05U)
- #define REG_SHUT_HI (0x06U)
- #define REG_SHUT_LO (0x07U)
- #define REG_PIX_MAX (0x08U)
- #define REG_PIX_ACCUM (0x09U)
- #define REG_PIX_MIN (0x0AU)
- #define REG_PIX_GRAB (0x0BU)
- #define REG_DELTA_XY_HIGH (0x0CU)
- #define REG_MOUSE_CTRL (0x0DU)
- #define REG_RUN_DOWNSHIFT (0x0EU)
- #define REG_REST1_PERIOD (0x0FU)
- #define REG_REST1_DOWNSHIFT (0x10U)
- #define REG_REST2_PERIOD (0x11U)
- #define REG_REST2_DOWNSHIFT (0x12U)
- #define REG_REST3_PERIOD (0x13U)
- #define REG_PERFORMANCE (0x22U)
- #define REG_RESET (0x3aU)
- #define REG_NOT_REV_ID (0x3fU)
- #define REG_LED_CTRL (0x40U)
- #define REG_MOTION_CTRL (0x41U)
- #define REG_BURST_READ_FIRST (0x42U)
- #define REG_BURST_READ_LAST (0x44U)
- #define REG_REST_MODE_CONFIG (0x45U)
- #define REG_MOTION_BURST (0x63U)
- #define REG_MOUSE_CTRL_POWERDOWN (0x02U)
- #define REG_MOTION_CTRL_MOT_A (0x80U)
- #define REG_MOTION_CTRL_MOT_S (0x40U)
- #define REG_MOUSE_CTRL_RES_EN (0x40U)
- #define REG_MOUSE_CTRL_BIT_REPORTING (0x80U)
- void adns2080_movement_read(int16_t * deltaX, int16_t * deltaY)
- {
- uint8_t delta_x;
- uint8_t delta_y;
- uint8_t delta_xy_high;
- uint8_t delta_x_high;
- uint8_t delta_y_high;
- uint16_t u16_deltaX;
- uint16_t u16_deltaY;
- delta_x = sdio_read_byte(REG_DELTA_X);
- delta_y = sdio_read_byte(REG_DELTA_Y);
- if (adns2080_motion_bits_read() == ADNS2080_MOTION_BITS_12)
- {
-
-
- delta_xy_high = sdio_read_byte(REG_DELTA_XY_HIGH);
- delta_x_high = ((delta_xy_high & 0xF0) >> 4);
- delta_y_high = (delta_xy_high & 0x0F);
-
-
- if (delta_x_high & 0x08)
- {
- u16_deltaX = 0xF000;
- }
- else
- {
- u16_deltaX = 0x0000;
- }
-
-
- if (delta_y_high & 0x08)
- {
- u16_deltaY = 0xF000;
- }
- else
- {
- u16_deltaY = 0x0000;
- }
- u16_deltaX |= (delta_x_high << 4) | delta_x;
- u16_deltaY |= (delta_y_high << 4) | delta_y;
- }
- else
- {
-
-
- if (delta_x & 0x80)
- {
- u16_deltaX = 0xFF00;
- }
- else
- {
- u16_deltaX = 0x0000;
- }
-
-
- if (delta_y & 0x80)
- {
- u16_deltaY = 0xFF00;
- }
- else
- {
- u16_deltaY = 0x0000;
- }
- u16_deltaX |= delta_x;
- u16_deltaY |= delta_y;
- }
- *deltaX = (int16_t)u16_deltaX;
- *deltaY = (int16_t)u16_deltaY;
- }
- adns2080_motion_bits_t adns2080_motion_bits_read(void)
- {
-
- return (adns2080_motion_bits_t)((sdio_read_byte(REG_MOUSE_CTRL) >> 7) & 0x01);
- }
- bool adns2080_is_motion_detected(void)
- {
- return ((sdio_read_byte(REG_MOTION_ST) & 0x80) != 0);
- }
- uint8_t adns2080_product_id_read(void)
- {
- return sdio_read_byte(REG_PROD_ID);
- }
- uint8_t adns2080_revision_id_read(void)
- {
- return sdio_read_byte(REG_REV_ID);
- }
- adns2080_status_t adns2080_init(void)
- {
- sdio_init();
- adns2080_reset();
- if (adns2080_product_id_read() != ADNS2080_PRODUCT_ID)
- {
- return ADNS2080_CHIP_NOT_DETECTED;
- }
- sdio_write_byte(REG_BURST_READ_FIRST, REG_DELTA_X);
- sdio_write_byte(REG_BURST_READ_LAST, REG_DELTA_Y);
- return ADNS2080_OK;
- }
- void adns2080_reset(void)
- {
- sdio_write_byte(REG_RESET, ADNS2080_RESET_NUMBER);
- }
- void adns2080_powerdown(void)
- {
- sdio_write_byte(REG_MOUSE_CTRL, REG_MOUSE_CTRL_POWERDOWN);
- }
- void adns2080_wakeup(void)
- {
- adns2080_reset();
- }
- adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity)
- {
- uint8_t databyte = 0;
- adns2080_status_t status = ADNS2080_OK;
- switch (polarity)
- {
- case ADNS2080_MOTION_OUTPUT_POLARITY_LOW:
- databyte = 0;
- break;
- case ADNS2080_MOTION_OUTPUT_POLARITY_HIGH:
- databyte = REG_MOTION_CTRL_MOT_A;
- break;
- default:
- status = ADNS2080_INVALID_PARAMETER;
- break;
- }
- switch (sensitivity)
- {
- case ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL:
- databyte &= ~(REG_MOTION_CTRL_MOT_S);
- break;
- case ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE:
- databyte |= (REG_MOTION_CTRL_MOT_S);
- break;
- default:
- status = ADNS2080_INVALID_PARAMETER;
- break;
- }
- if (status == ADNS2080_OK)
- {
- sdio_write_byte(REG_MOTION_CTRL, databyte);
- }
- return status;
- }
- adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution)
- {
- uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL);
- adns2080_status_t status = ADNS2080_OK;
-
- databyte |= (REG_MOUSE_CTRL_RES_EN);
- switch (resolution)
- {
- case ADNS2080_RESOLUTION_250DPI:
- case ADNS2080_RESOLUTION_500DPI:
- case ADNS2080_RESOLUTION_1000DPI:
- case ADNS2080_RESOLUTION_1250DPI:
- case ADNS2080_RESOLUTION_1500DPI:
- case ADNS2080_RESOLUTION_1750DPI:
- case ADNS2080_RESOLUTION_2000DPI:
-
- databyte &= ~(0x1C);
-
- databyte |= (uint8_t)((uint8_t)resolution << 2);
- break;
- default:
- status = ADNS2080_INVALID_PARAMETER;
- break;
- }
- if (status == ADNS2080_OK)
- {
- sdio_write_byte(REG_MOUSE_CTRL, databyte);
- }
- return status;
- }
- adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits)
- {
- uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL);
- adns2080_status_t status = ADNS2080_OK;
- switch (motion_bits)
- {
- case ADNS2080_MOTION_BITS_8:
- databyte &= ~(REG_MOUSE_CTRL_BIT_REPORTING);
- break;
- case ADNS2080_MOTION_BITS_12:
- databyte |= (REG_MOUSE_CTRL_BIT_REPORTING);
- break;
- default:
- status = ADNS2080_INVALID_PARAMETER;
- break;
- }
- if (status == ADNS2080_OK)
- {
- sdio_write_byte(REG_MOUSE_CTRL, databyte);
- }
- return status;
- }
- void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period)
- {
- adns2080_mode_t current_mode = adns2080_force_mode_read();
- adns2080_force_mode_set(ADNS2080_MODE_RUN1);
- sdio_write_byte(REG_REST1_PERIOD, rest1_period);
- sdio_write_byte(REG_REST2_PERIOD, rest2_period);
- sdio_write_byte(REG_REST3_PERIOD, rest3_period);
- adns2080_force_mode_set(current_mode);
- }
- void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time)
- {
- adns2080_mode_t current_mode = adns2080_force_mode_read();
- adns2080_force_mode_set(ADNS2080_MODE_RUN1);
- sdio_write_byte(REG_RUN_DOWNSHIFT, run_to_rest1_mode_time);
- sdio_write_byte(REG_REST1_DOWNSHIFT, rest1_to_rest2_mode_time);
- sdio_write_byte(REG_REST2_DOWNSHIFT, rest2_to_rest3_mode_time);
- adns2080_force_mode_set(current_mode);
- }
- adns2080_mode_t adns2080_force_mode_read(void)
- {
- return (adns2080_mode_t)((sdio_read_byte(REG_PERFORMANCE) >> 4) & 0x07);
- }
- void adns2080_force_mode_set(adns2080_mode_t mode)
- {
- sdio_write_byte(REG_PERFORMANCE, (uint8_t)((uint8_t)mode << 4));
- }
|