You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.2 KiB

  1. /* Copyright 2021 Colin Lam (Ploopy Corporation)
  2. * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
  3. * Copyright 2019 Sunjun Kim
  4. * Copyright 2019 Hiroyuki Okada
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "adns5050.h"
  20. #include "wait.h"
  21. #include "debug.h"
  22. #include "print.h"
  23. #include "gpio.h"
  24. #ifndef OPTIC_ROTATED
  25. # define OPTIC_ROTATED false
  26. #endif
  27. // Definitions for the ADNS serial line.
  28. #ifndef ADNS_SCLK_PIN
  29. # define ADNS_SCLK_PIN B7
  30. #endif
  31. #ifndef ADNS_SDIO_PIN
  32. # define ADNS_SDIO_PIN C6
  33. #endif
  34. #ifndef ADNS_CS_PIN
  35. # define ADNS_CS_PIN B4
  36. #endif
  37. #ifdef CONSOLE_ENABLE
  38. 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')); }
  39. #endif
  40. // Initialize the ADNS serial pins.
  41. void adns_init(void) {
  42. setPinOutput(ADNS_SCLK_PIN);
  43. setPinOutput(ADNS_SDIO_PIN);
  44. setPinOutput(ADNS_CS_PIN);
  45. }
  46. // Perform a synchronization with the ADNS.
  47. // Just as with the serial protocol, this is used by the slave to send a
  48. // synchronization signal to the master.
  49. void adns_sync(void) {
  50. writePinLow(ADNS_CS_PIN);
  51. wait_us(1);
  52. writePinHigh(ADNS_CS_PIN);
  53. }
  54. void adns_cs_select(void) { writePinLow(ADNS_CS_PIN); }
  55. void adns_cs_deselect(void) { writePinHigh(ADNS_CS_PIN); }
  56. uint8_t adns_serial_read(void) {
  57. setPinInput(ADNS_SDIO_PIN);
  58. uint8_t byte = 0;
  59. for (uint8_t i = 0; i < 8; ++i) {
  60. writePinLow(ADNS_SCLK_PIN);
  61. wait_us(1);
  62. byte = (byte << 1) | readPin(ADNS_SDIO_PIN);
  63. writePinHigh(ADNS_SCLK_PIN);
  64. wait_us(1);
  65. }
  66. return byte;
  67. }
  68. void adns_serial_write(uint8_t data) {
  69. setPinOutput(ADNS_SDIO_PIN);
  70. for (int8_t b = 7; b >= 0; b--) {
  71. writePinLow(ADNS_SCLK_PIN);
  72. if (data & (1 << b))
  73. writePinHigh(ADNS_SDIO_PIN);
  74. else
  75. writePinLow(ADNS_SDIO_PIN);
  76. wait_us(2);
  77. writePinHigh(ADNS_SCLK_PIN);
  78. }
  79. // tSWR. See page 15 of the ADNS spec sheet.
  80. // Technically, this is only necessary if the next operation is an SDIO
  81. // read. This is not guaranteed to be the case, but we're being lazy.
  82. wait_us(4);
  83. // Note that tSWW is never necessary. All write operations require at
  84. // least 32us, which exceeds tSWW, so there's never a need to wait for it.
  85. }
  86. // Read a byte of data from a register on the ADNS.
  87. // Don't forget to use the register map (as defined in the header file).
  88. uint8_t adns_read_reg(uint8_t reg_addr) {
  89. adns_cs_select();
  90. adns_serial_write(reg_addr);
  91. // We don't need a minimum tSRAD here. That's because a 4ms wait time is
  92. // already included in adns_serial_write(), so we're good.
  93. // See page 10 and 15 of the ADNS spec sheet.
  94. // wait_us(4);
  95. uint8_t byte = adns_serial_read();
  96. // tSRW & tSRR. See page 15 of the ADNS spec sheet.
  97. // Technically, this is only necessary if the next operation is an SDIO
  98. // read or write. This is not guaranteed to be the case.
  99. // Honestly, this wait could probably be removed.
  100. wait_us(1);
  101. adns_cs_deselect();
  102. return byte;
  103. }
  104. void adns_write_reg(uint8_t reg_addr, uint8_t data) {
  105. adns_cs_select();
  106. adns_serial_write(0b10000000 | reg_addr);
  107. adns_serial_write(data);
  108. adns_cs_deselect();
  109. }
  110. report_adns_t adns_read_burst(void) {
  111. adns_cs_select();
  112. report_adns_t data;
  113. data.dx = 0;
  114. data.dy = 0;
  115. adns_serial_write(REG_MOTION_BURST);
  116. // We don't need a minimum tSRAD here. That's because a 4ms wait time is
  117. // already included in adns_serial_write(), so we're good.
  118. // See page 10 and 15 of the ADNS spec sheet.
  119. // wait_us(4);
  120. uint8_t x = adns_serial_read();
  121. uint8_t y = adns_serial_read();
  122. // Burst mode returns a bunch of other shit that we don't really need.
  123. // Setting CS to high ends burst mode early.
  124. adns_cs_deselect();
  125. data.dx = convert_twoscomp(x);
  126. data.dy = convert_twoscomp(y);
  127. return data;
  128. }
  129. // Convert a two's complement byte from an unsigned data type into a signed
  130. // data type.
  131. int8_t convert_twoscomp(uint8_t data) {
  132. if ((data & 0x80) == 0x80)
  133. return -128 + (data & 0x7F);
  134. else
  135. return data;
  136. }
  137. // Don't forget to use the definitions for CPI in the header file.
  138. void adns_set_cpi(uint8_t cpi) { adns_write_reg(REG_MOUSE_CONTROL2, cpi); }
  139. bool adns_check_signature(void) {
  140. uint8_t pid = adns_read_reg(REG_PRODUCT_ID);
  141. uint8_t rid = adns_read_reg(REG_REVISION_ID);
  142. uint8_t pid2 = adns_read_reg(REG_PRODUCT_ID2);
  143. return (pid == 0x12 && rid == 0x01 && pid2 == 0x26);
  144. }