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.

270 lines
7.5 KiB

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include "quantum.h"
  4. #include "pointing_device.h"
  5. #include "adns9800_srom_A4.h"
  6. #include <LUFA/Drivers/Peripheral/SPI.h>
  7. // registers
  8. #define REG_Product_ID 0x00
  9. #define REG_Revision_ID 0x01
  10. #define REG_Motion 0x02
  11. #define REG_Delta_X_L 0x03
  12. #define REG_Delta_X_H 0x04
  13. #define REG_Delta_Y_L 0x05
  14. #define REG_Delta_Y_H 0x06
  15. #define REG_SQUAL 0x07
  16. #define REG_Pixel_Sum 0x08
  17. #define REG_Maximum_Pixel 0x09
  18. #define REG_Minimum_Pixel 0x0a
  19. #define REG_Shutter_Lower 0x0b
  20. #define REG_Shutter_Upper 0x0c
  21. #define REG_Frame_Period_Lower 0x0d
  22. #define REG_Frame_Period_Upper 0x0e
  23. #define REG_Configuration_I 0x0f
  24. #define REG_Configuration_II 0x10
  25. #define REG_Frame_Capture 0x12
  26. #define REG_SROM_Enable 0x13
  27. #define REG_Run_Downshift 0x14
  28. #define REG_Rest1_Rate 0x15
  29. #define REG_Rest1_Downshift 0x16
  30. #define REG_Rest2_Rate 0x17
  31. #define REG_Rest2_Downshift 0x18
  32. #define REG_Rest3_Rate 0x19
  33. #define REG_Frame_Period_Max_Bound_Lower 0x1a
  34. #define REG_Frame_Period_Max_Bound_Upper 0x1b
  35. #define REG_Frame_Period_Min_Bound_Lower 0x1c
  36. #define REG_Frame_Period_Min_Bound_Upper 0x1d
  37. #define REG_Shutter_Max_Bound_Lower 0x1e
  38. #define REG_Shutter_Max_Bound_Upper 0x1f
  39. #define REG_LASER_CTRL0 0x20
  40. #define REG_Observation 0x24
  41. #define REG_Data_Out_Lower 0x25
  42. #define REG_Data_Out_Upper 0x26
  43. #define REG_SROM_ID 0x2a
  44. #define REG_Lift_Detection_Thr 0x2e
  45. #define REG_Configuration_V 0x2f
  46. #define REG_Configuration_IV 0x39
  47. #define REG_Power_Up_Reset 0x3a
  48. #define REG_Shutdown 0x3b
  49. #define REG_Inverse_Product_ID 0x3f
  50. #define REG_Motion_Burst 0x50
  51. #define REG_SROM_Load_Burst 0x62
  52. #define REG_Pixel_Burst 0x64
  53. // pins
  54. #define NCS 0
  55. extern const uint16_t firmware_length;
  56. extern const uint8_t firmware_data[];
  57. enum motion_burst_property{
  58. motion = 0,
  59. observation,
  60. delta_x_l,
  61. delta_x_h,
  62. delta_y_l,
  63. delta_y_h,
  64. squal,
  65. pixel_sum,
  66. maximum_pixel,
  67. minimum_pixel,
  68. shutter_upper,
  69. shutter_lower,
  70. frame_period_upper,
  71. frame_period_lower,
  72. end_data
  73. };
  74. // used to track the motion delta between updates
  75. volatile int32_t delta_x;
  76. volatile int32_t delta_y;
  77. void adns_begin(void){
  78. PORTB &= ~ (1 << NCS);
  79. }
  80. void adns_end(void){
  81. PORTB |= (1 << NCS);
  82. }
  83. void adns_write(uint8_t reg_addr, uint8_t data){
  84. adns_begin();
  85. //send address of the register, with MSBit = 1 to indicate it's a write
  86. SPI_TransferByte(reg_addr | 0x80 );
  87. SPI_TransferByte(data);
  88. // tSCLK-NCS for write operation
  89. wait_us(20);
  90. adns_end();
  91. // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
  92. wait_us(100);
  93. }
  94. uint8_t adns_read(uint8_t reg_addr){
  95. adns_begin();
  96. // send adress of the register, with MSBit = 0 to indicate it's a read
  97. SPI_TransferByte(reg_addr & 0x7f );
  98. uint8_t data = SPI_TransferByte(0);
  99. // tSCLK-NCS for read operation is 120ns
  100. wait_us(1);
  101. adns_end();
  102. // tSRW/tSRR (=20us) minus tSCLK-NCS
  103. wait_us(19);
  104. return data;
  105. }
  106. void pointing_device_init(void) {
  107. if(!is_keyboard_master())
  108. return;
  109. // interrupt 2
  110. EICRA &= ~(1 << 4);
  111. EICRA |= (1 << 5);
  112. EIMSK |= (1<<INT2);
  113. // mode 3
  114. SPI_Init(
  115. SPI_SPEED_FCPU_DIV_8 |
  116. SPI_ORDER_MSB_FIRST |
  117. SPI_SCK_LEAD_FALLING |
  118. SPI_SAMPLE_TRAILING |
  119. SPI_MODE_MASTER);
  120. // set B0 output
  121. DDRB |= (1 << 0);
  122. // reset serial port
  123. adns_end();
  124. adns_begin();
  125. adns_end();
  126. // reboot
  127. adns_write(REG_Power_Up_Reset, 0x5a);
  128. wait_ms(50);
  129. // read registers and discard
  130. adns_read(REG_Motion);
  131. adns_read(REG_Delta_X_L);
  132. adns_read(REG_Delta_X_H);
  133. adns_read(REG_Delta_Y_L);
  134. adns_read(REG_Delta_Y_H);
  135. // upload firmware
  136. // set the configuration_IV register in 3k firmware mode
  137. // bit 1 = 1 for 3k mode, other bits are reserved
  138. adns_write(REG_Configuration_IV, 0x02);
  139. // write 0x1d in SROM_enable reg for initializing
  140. adns_write(REG_SROM_Enable, 0x1d);
  141. // wait for more than one frame period
  142. // assume that the frame rate is as low as 100fps... even if it should never be that low
  143. wait_ms(10);
  144. // write 0x18 to SROM_enable to start SROM download
  145. adns_write(REG_SROM_Enable, 0x18);
  146. // write the SROM file (=firmware data)
  147. adns_begin();
  148. // write burst destination adress
  149. SPI_TransferByte(REG_SROM_Load_Burst | 0x80);
  150. wait_us(15);
  151. // send all bytes of the firmware
  152. unsigned char c;
  153. for(int i = 0; i < firmware_length; i++){
  154. c = (unsigned char)pgm_read_byte(firmware_data + i);
  155. SPI_TransferByte(c);
  156. wait_us(15);
  157. }
  158. adns_end();
  159. wait_ms(10);
  160. // enable laser(bit 0 = 0b), in normal mode (bits 3,2,1 = 000b)
  161. // reading the actual value of the register is important because the real
  162. // default value is different from what is said in the datasheet, and if you
  163. // change the reserved bytes (like by writing 0x00...) it would not work.
  164. uint8_t laser_ctrl0 = adns_read(REG_LASER_CTRL0);
  165. adns_write(REG_LASER_CTRL0, laser_ctrl0 & 0xf0);
  166. wait_ms(1);
  167. // set the configuration_I register to set the CPI
  168. // 0x01 = 50, minimum
  169. // 0x44 = 3400, default
  170. // 0x8e = 7100
  171. // 0xA4 = 8200, maximum
  172. adns_write(REG_Configuration_I, 0x04);
  173. wait_ms(100);
  174. }
  175. void pointing_device_task(void) {
  176. if(!is_keyboard_master())
  177. return;
  178. report_mouse_t report = pointing_device_get_report();
  179. // clamp deltas from -127 to 127
  180. report.x = delta_x < -127 ? 127 : delta_x > 127 ? 127 : delta_x;
  181. report.x = -report.x;
  182. report.y = delta_y < -127 ? 127 : delta_y > 127 ? 127 : delta_y;
  183. // reset deltas
  184. delta_x = 0;
  185. delta_y = 0;
  186. pointing_device_set_report(report);
  187. pointing_device_send();
  188. }
  189. int16_t convertDeltaToInt(uint8_t high, uint8_t low){
  190. // join bytes into twos compliment
  191. uint16_t twos_comp = (high << 8) | low;
  192. // convert twos comp to int
  193. if (twos_comp & 0x8000)
  194. return -1 * ((twos_comp ^ 0xffff) + 1);
  195. return twos_comp;
  196. }
  197. ISR(INT2_vect) {
  198. // called on interrupt 2 when sensed motion
  199. // copy burst data from the respective registers
  200. adns_begin();
  201. // send adress of the register, with MSBit = 1 to indicate it's a write
  202. SPI_TransferByte(REG_Motion_Burst & 0x7f);
  203. uint8_t burst_data[pixel_sum];
  204. for (int i = 0; i < pixel_sum; ++i) {
  205. burst_data[i] = SPI_TransferByte(0);
  206. }
  207. delta_x += convertDeltaToInt(burst_data[delta_x_h], burst_data[delta_x_l]);
  208. delta_y += convertDeltaToInt(burst_data[delta_y_h], burst_data[delta_y_l]);
  209. adns_end();
  210. }