updated firmware with latest changes
This commit is contained in:
		
							parent
							
								
									dc0bd0c2f3
								
							
						
					
					
						commit
						f5688b925e
					
				| 
						 | 
					@ -19,79 +19,50 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <SPI.h>
 | 
					#include <SPI.h>
 | 
				
			||||||
#include <avr/pgmspace.h>
 | 
					#include <avr/pgmspace.h>
 | 
				
			||||||
 | 
					#include <avr/wdt.h>
 | 
				
			||||||
#include "AdvMouse.h"
 | 
					#include "AdvMouse.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Max recommended is 4,000,000, since clock speed is 8MHz.
 | 
				
			||||||
 | 
					// If lower, it should be by factors of 1/2.
 | 
				
			||||||
 | 
					static const int SPIMAXIMUMSPEED = 2000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int CPI = 1200;
 | 
				
			||||||
 | 
					static const int DEBOUNCE = 10; // ms
 | 
				
			||||||
 | 
					static const int SCROLL_DEBOUNCE = 50; // ms
 | 
				
			||||||
 | 
					static const int SCROLL_BUTT_DEBOUNCE = 100; // ms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const float ROTATIONAL_TRANSFORM_ANGLE = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int MOUSE_LEFT_PIN = 4;
 | 
				
			||||||
 | 
					static const int MOUSE_RIGHT_PIN = 7;
 | 
				
			||||||
 | 
					static const int MOUSE_MIDDLE_PIN = 0;
 | 
				
			||||||
 | 
					static const int MOUSE_BACK_PIN = 9;
 | 
				
			||||||
 | 
					static const int MOUSE_FORWARD_PIN = 6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// For info, see https://forum.arduino.cc/index.php?topic=241369.0
 | 
				
			||||||
 | 
					static const int SENSOR_CS = 17;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int OPT_ENC_PIN1 = A3;
 | 
				
			||||||
 | 
					static const int OPT_ENC_PIN2 = A5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int OPT_LOW_THRESHOLD = 150;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const byte MOTION = 0x02;
 | 
				
			||||||
 | 
					static const byte DELTA_X_L = 0x03;
 | 
				
			||||||
 | 
					static const byte DELTA_X_H = 0x04;
 | 
				
			||||||
 | 
					static const byte DELTA_Y_L = 0x05;
 | 
				
			||||||
 | 
					static const byte DELTA_Y_H = 0x06;
 | 
				
			||||||
 | 
					static const byte CONFIG1 = 0x0F;
 | 
				
			||||||
 | 
					static const byte CONFIG2 = 0x10;
 | 
				
			||||||
 | 
					static const byte SROM_ENABLE = 0x13;
 | 
				
			||||||
 | 
					static const byte SROM_ID = 0x2A;
 | 
				
			||||||
 | 
					static const byte POWER_UP_RESET = 0x3A;
 | 
				
			||||||
 | 
					static const byte SHUTDOWN = 0x3B;
 | 
				
			||||||
 | 
					static const byte MOTION_BURST = 0x50;
 | 
				
			||||||
 | 
					static const byte SROM_LOAD_BURST = 0x62;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
boolean debugMode = false;
 | 
					boolean debugMode = false;
 | 
				
			||||||
 | 
					boolean wdtMode = false;
 | 
				
			||||||
const static int CPI = 1200;
 | 
					 | 
				
			||||||
const static int DEBOUNCE = 10; // ms
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const static float ROTATIONAL_TRANSFORM_ANGLE = 27.5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const static int MOUSE_LEFT_PIN = 4;
 | 
					 | 
				
			||||||
const static int MOUSE_RIGHT_PIN = 7;
 | 
					 | 
				
			||||||
const static int MOUSE_MIDDLE_PIN = 0;
 | 
					 | 
				
			||||||
const static int MOUSE_BACK_PIN = 9;
 | 
					 | 
				
			||||||
const static int MOUSE_FORWARD_PIN = 6;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const static int OPT_ENC_PIN1 = A3;
 | 
					 | 
				
			||||||
const static int OPT_ENC_PIN2 = A5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const static int OPT_LOW_THRESHOLD = 100;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const static byte Product_ID = 0x00;
 | 
					 | 
				
			||||||
const static byte Revision_ID = 0x01;
 | 
					 | 
				
			||||||
const static byte Motion = 0x02;
 | 
					 | 
				
			||||||
const static byte Delta_X_L = 0x03;
 | 
					 | 
				
			||||||
const static byte Delta_X_H = 0x04;
 | 
					 | 
				
			||||||
const static byte Delta_Y_L = 0x05;
 | 
					 | 
				
			||||||
const static byte Delta_Y_H = 0x06;
 | 
					 | 
				
			||||||
const static byte SQUAL = 0x07;
 | 
					 | 
				
			||||||
const static byte Raw_Data_Sum = 0x08;
 | 
					 | 
				
			||||||
const static byte Maximum_Raw_data = 0x09;
 | 
					 | 
				
			||||||
const static byte Minimum_Raw_data = 0x0A;
 | 
					 | 
				
			||||||
const static byte Shutter_Lower = 0x0B;
 | 
					 | 
				
			||||||
const static byte Shutter_Upper = 0x0C;
 | 
					 | 
				
			||||||
const static byte Control = 0x0D;
 | 
					 | 
				
			||||||
const static byte Config1 = 0x0F;
 | 
					 | 
				
			||||||
const static byte Config2 = 0x10;
 | 
					 | 
				
			||||||
const static byte Angle_Tune = 0x11;
 | 
					 | 
				
			||||||
const static byte Frame_Capture = 0x12;
 | 
					 | 
				
			||||||
const static byte SROM_Enable = 0x13;
 | 
					 | 
				
			||||||
const static byte Run_Downshift = 0x14;
 | 
					 | 
				
			||||||
const static byte Rest1_Rate_Lower = 0x15;
 | 
					 | 
				
			||||||
const static byte Rest1_Rate_Upper = 0x16;
 | 
					 | 
				
			||||||
const static byte Rest1_Downshift = 0x17;
 | 
					 | 
				
			||||||
const static byte Rest2_Rate_Lower = 0x18;
 | 
					 | 
				
			||||||
const static byte Rest2_Rate_Upper = 0x19;
 | 
					 | 
				
			||||||
const static byte Rest2_Downshift = 0x1A;
 | 
					 | 
				
			||||||
const static byte Rest3_Rate_Lower = 0x1B;
 | 
					 | 
				
			||||||
const static byte Rest3_Rate_Upper = 0x1C;
 | 
					 | 
				
			||||||
const static byte Observation = 0x24;
 | 
					 | 
				
			||||||
const static byte Data_Out_Lower = 0x25;
 | 
					 | 
				
			||||||
const static byte Data_Out_Upper = 0x26;
 | 
					 | 
				
			||||||
const static byte Raw_Data_Dump = 0x29;
 | 
					 | 
				
			||||||
const static byte SROM_ID = 0x2A;
 | 
					 | 
				
			||||||
const static byte Min_SQ_Run = 0x2B;
 | 
					 | 
				
			||||||
const static byte Raw_Data_Threshold = 0x2C;
 | 
					 | 
				
			||||||
const static byte Config5 = 0x2F;
 | 
					 | 
				
			||||||
const static byte Power_Up_Reset = 0x3A;
 | 
					 | 
				
			||||||
const static byte Shutdown = 0x3B;
 | 
					 | 
				
			||||||
const static byte Inverse_Product_ID = 0x3F;
 | 
					 | 
				
			||||||
const static byte LiftCutoff_Tune3 = 0x41;
 | 
					 | 
				
			||||||
const static byte Angle_Snap = 0x42;
 | 
					 | 
				
			||||||
const static byte LiftCutoff_Tune1 = 0x4A;
 | 
					 | 
				
			||||||
const static byte Motion_Burst = 0x50;
 | 
					 | 
				
			||||||
const static byte LiftCutoff_Tune_Timeout = 0x58;
 | 
					 | 
				
			||||||
const static byte LiftCutoff_Tune_Min_Length = 0x5A;
 | 
					 | 
				
			||||||
const static byte SROM_Load_Burst = 0x62;
 | 
					 | 
				
			||||||
const static byte Lift_Config = 0x63;
 | 
					 | 
				
			||||||
const static byte Raw_Data_Burst = 0x64;
 | 
					 | 
				
			||||||
const static byte LiftCutoff_Tune2 = 0x65;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Pin 17? WHAA? Curious? See here:
 | 
					 | 
				
			||||||
// https://forum.arduino.cc/index.php?topic=241369.0
 | 
					 | 
				
			||||||
const static int SENSOR_CS = 17;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
float cosTransform;
 | 
					float cosTransform;
 | 
				
			||||||
float sinTransform;
 | 
					float sinTransform;
 | 
				
			||||||
| 
						 | 
					@ -111,63 +82,40 @@ int16_t dy;
 | 
				
			||||||
unsigned long lastTS;
 | 
					unsigned long lastTS;
 | 
				
			||||||
unsigned long lastButtonCheck = 0;
 | 
					unsigned long lastButtonCheck = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long lastScroll = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long middleClickRelease = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const unsigned short firmware_length;
 | 
					extern const unsigned short firmware_length;
 | 
				
			||||||
extern const unsigned char firmware_data[];
 | 
					extern const unsigned char firmware_data[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup() {
 | 
					void setup() {
 | 
				
			||||||
 | 
					  if (wdtMode) {
 | 
				
			||||||
 | 
					    setupWDT();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (debugMode) {
 | 
					  if (debugMode) {
 | 
				
			||||||
    pinMode(A0, OUTPUT);
 | 
					    Serial.begin(9600);
 | 
				
			||||||
    digitalWrite(A0, HIGH);
 | 
					 | 
				
			||||||
    //delay(5000);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Startup delay. This sometimes prevents a USB handshake lockup.
 | 
					  // Startup delay. This sometimes prevents a USB handshake lockup.
 | 
				
			||||||
  delay(1000);
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Serial.begin(9600);
 | 
					  setupPins();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinMode(SENSOR_CS, OUTPUT);
 | 
					  // This is the debug LED.
 | 
				
			||||||
  pinMode(MOUSE_LEFT_PIN, INPUT_PULLUP);
 | 
					  pinMode(A0, OUTPUT);
 | 
				
			||||||
  pinMode(MOUSE_RIGHT_PIN, INPUT_PULLUP);
 | 
					  if (debugMode) {
 | 
				
			||||||
  pinMode(MOUSE_MIDDLE_PIN, INPUT_PULLUP);
 | 
					    digitalWrite(A0, HIGH);
 | 
				
			||||||
  pinMode(MOUSE_BACK_PIN, INPUT_PULLUP);
 | 
					  } else {
 | 
				
			||||||
  pinMode(MOUSE_FORWARD_PIN, INPUT_PULLUP);
 | 
					    digitalWrite(A0, LOW);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  pinMode(OPT_ENC_PIN1, INPUT);
 | 
					 | 
				
			||||||
  pinMode(OPT_ENC_PIN2, INPUT);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Ground all output pins connected to ground.
 | 
					 | 
				
			||||||
  // This provides additional pathways to ground.
 | 
					 | 
				
			||||||
  // If you're messing with this, know this:
 | 
					 | 
				
			||||||
  // Driving ANY of these pins high will cause a short.
 | 
					 | 
				
			||||||
  // On the MCU.
 | 
					 | 
				
			||||||
  // Ka-blooey.
 | 
					 | 
				
			||||||
  pinMode(1, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(2, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(8, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(10, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(11, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(12, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(13, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(A1, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(A2, OUTPUT);
 | 
					 | 
				
			||||||
  pinMode(A4, OUTPUT);
 | 
					 | 
				
			||||||
  digitalWrite(1, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(2, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(8, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(10, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(11, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(12, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(13, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(A1, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(A2, LOW);
 | 
					 | 
				
			||||||
  digitalWrite(A4, LOW);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SPI.begin();
 | 
					  SPI.begin();
 | 
				
			||||||
  SPI.setDataMode(SPI_MODE3);
 | 
					  SPI.setDataMode(SPI_MODE3);
 | 
				
			||||||
  SPI.setBitOrder(MSBFIRST);
 | 
					  SPI.setBitOrder(MSBFIRST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  performStartup();
 | 
					  initialisePMW3360();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cosTransform = cos(ROTATIONAL_TRANSFORM_ANGLE * PI / 180);
 | 
					  cosTransform = cos(ROTATIONAL_TRANSFORM_ANGLE * PI / 180);
 | 
				
			||||||
  sinTransform = sin(ROTATIONAL_TRANSFORM_ANGLE * PI / 180);
 | 
					  sinTransform = sin(ROTATIONAL_TRANSFORM_ANGLE * PI / 180);
 | 
				
			||||||
| 
						 | 
					@ -188,16 +136,80 @@ void setup() {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void adns_com_begin() {
 | 
					void setupWDT() {
 | 
				
			||||||
 | 
					  /* IMPORTANT NOTE!
 | 
				
			||||||
 | 
					   * THIS MUST BE THE FIRST THING THAT RUNS IN SETUP()! If it isn't, there's
 | 
				
			||||||
 | 
					   * a good chance the Arduino will enter an unstable state, and it's entirely
 | 
				
			||||||
 | 
					   * possible that you can permanently brick your MCU!
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cli();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Clear the watchdog reset flag
 | 
				
			||||||
 | 
					  MCUSR &= ~(1 << WDRF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Enter watchdog configuration mode
 | 
				
			||||||
 | 
					  WDTCSR |= (1 << WDCE) |
 | 
				
			||||||
 | 
					            (1 << WDE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // WDIE needs to be included, or else this doesn't work.
 | 
				
			||||||
 | 
					  WDTCSR = (1 << WDIE) |
 | 
				
			||||||
 | 
					           (1 << WDE) |
 | 
				
			||||||
 | 
					           (1 << WDP3) |
 | 
				
			||||||
 | 
					           (0 << WDP2) |
 | 
				
			||||||
 | 
					           (0 << WDP1) |
 | 
				
			||||||
 | 
					           (0 << WDP0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sei();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setupPins() {
 | 
				
			||||||
 | 
					  pinMode(SENSOR_CS, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(MOUSE_LEFT_PIN, INPUT_PULLUP);
 | 
				
			||||||
 | 
					  pinMode(MOUSE_RIGHT_PIN, INPUT_PULLUP);
 | 
				
			||||||
 | 
					  pinMode(MOUSE_MIDDLE_PIN, INPUT_PULLUP);
 | 
				
			||||||
 | 
					  pinMode(MOUSE_BACK_PIN, INPUT_PULLUP);
 | 
				
			||||||
 | 
					  pinMode(MOUSE_FORWARD_PIN, INPUT_PULLUP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinMode(OPT_ENC_PIN1, INPUT);
 | 
				
			||||||
 | 
					  pinMode(OPT_ENC_PIN2, INPUT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Ground all output pins connected to ground. This provides additional
 | 
				
			||||||
 | 
					   * pathways to ground. If you're messing with this, know this: driving ANY
 | 
				
			||||||
 | 
					   * of these pins high will cause a short. On the MCU. Ka-blooey.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  pinMode(1, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(2, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(8, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(10, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(11, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(12, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(13, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(A1, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(A2, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(A4, OUTPUT);
 | 
				
			||||||
 | 
					  digitalWrite(1, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(2, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(8, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(10, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(11, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(12, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(13, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(A1, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(A2, LOW);
 | 
				
			||||||
 | 
					  digitalWrite(A4, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void adnsComBegin() {
 | 
				
			||||||
  digitalWrite(SENSOR_CS, LOW);
 | 
					  digitalWrite(SENSOR_CS, LOW);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void adns_com_end() {
 | 
					void adnsComEnd() {
 | 
				
			||||||
  digitalWrite(SENSOR_CS, HIGH);
 | 
					  digitalWrite(SENSOR_CS, HIGH);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
byte adns_read_reg(byte reg_addr) {
 | 
					byte adnsReadReg(byte reg_addr) {
 | 
				
			||||||
  adns_com_begin();
 | 
					  adnsComBegin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // send adress of the register, with MSBit = 0 to indicate it's a read
 | 
					  // send adress of the register, with MSBit = 0 to indicate it's a read
 | 
				
			||||||
  SPI.transfer(reg_addr & 0x7f);
 | 
					  SPI.transfer(reg_addr & 0x7f);
 | 
				
			||||||
| 
						 | 
					@ -206,15 +218,15 @@ byte adns_read_reg(byte reg_addr) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // tSCLK-SENSOR_CS for read operation is 120ns
 | 
					  // tSCLK-SENSOR_CS for read operation is 120ns
 | 
				
			||||||
  delayMicroseconds(1);
 | 
					  delayMicroseconds(1);
 | 
				
			||||||
  adns_com_end();
 | 
					  adnsComEnd();
 | 
				
			||||||
  // tSRW/tSRR (=20us) minus tSCLK-SENSOR_CS
 | 
					  // tSRW/tSRR (=20us) minus tSCLK-SENSOR_CS
 | 
				
			||||||
  delayMicroseconds(19);
 | 
					  delayMicroseconds(19);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return data;
 | 
					  return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void adns_write_reg(byte reg_addr, byte data) {
 | 
					void adnsWriteReg(byte reg_addr, byte data) {
 | 
				
			||||||
  adns_com_begin();
 | 
					  adnsComBegin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // send adress of the register, with MSBit = 1 to indicate it's a write
 | 
					  // send adress of the register, with MSBit = 1 to indicate it's a write
 | 
				
			||||||
  SPI.transfer(reg_addr | 0x80);
 | 
					  SPI.transfer(reg_addr | 0x80);
 | 
				
			||||||
| 
						 | 
					@ -222,33 +234,78 @@ void adns_write_reg(byte reg_addr, byte data) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // tSCLK-SENSOR_CS for write operation
 | 
					  // tSCLK-SENSOR_CS for write operation
 | 
				
			||||||
  delayMicroseconds(20);
 | 
					  delayMicroseconds(20);
 | 
				
			||||||
  adns_com_end();
 | 
					  adnsComEnd();
 | 
				
			||||||
  // tSWW/tSWR (=120us) minus tSCLK-SENSOR_CS.
 | 
					  // tSWW/tSWR (=120us) minus tSCLK-SENSOR_CS.
 | 
				
			||||||
  // Could be shortened, but this looks like a safe lower-bound.
 | 
					  // Could be shortened, but this looks like a safe lower-bound.
 | 
				
			||||||
  delayMicroseconds(100);
 | 
					  delayMicroseconds(100);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void adns_upload_firmware() {
 | 
					void setCPI(int cpi) {
 | 
				
			||||||
 | 
					  int cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  adnsComBegin();
 | 
				
			||||||
 | 
					  adnsWriteReg(CONFIG1, cpival);
 | 
				
			||||||
 | 
					  adnsComEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (debugMode) {
 | 
				
			||||||
 | 
					    Serial.print(F("Got "));
 | 
				
			||||||
 | 
					    Serial.println(cpi);
 | 
				
			||||||
 | 
					    Serial.print(F("Set cpi to "));
 | 
				
			||||||
 | 
					    Serial.println((cpival + 1) * 100);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void initialisePMW3360(void) {
 | 
				
			||||||
 | 
					  if (debugMode) {
 | 
				
			||||||
 | 
					    Serial.println(F("Initialising PMW3360"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Hard reset. Start by ensuring that the serial port is reset.
 | 
				
			||||||
 | 
					  adnsComEnd();
 | 
				
			||||||
 | 
					  adnsComBegin();
 | 
				
			||||||
 | 
					  adnsComEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // SHUTDOWN the PMW3360, in case the microcontroller reset but the sensor didn't.
 | 
				
			||||||
 | 
					  adnsWriteReg(SHUTDOWN, 0xb6);
 | 
				
			||||||
 | 
					  delay(300);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Drop and raise SENSOR_CS to reset the spi port
 | 
				
			||||||
 | 
					  adnsComBegin();
 | 
				
			||||||
 | 
					  delayMicroseconds(40);
 | 
				
			||||||
 | 
					  adnsComEnd();
 | 
				
			||||||
 | 
					  delayMicroseconds(40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Force a reset of the PMW3360.
 | 
				
			||||||
 | 
					  adnsWriteReg(POWER_UP_RESET, 0x5a);
 | 
				
			||||||
 | 
					  delay(50);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Read registers 0x02 through 0x06 (and discard the data)
 | 
				
			||||||
 | 
					  adnsReadReg(MOTION);
 | 
				
			||||||
 | 
					  adnsReadReg(DELTA_X_L);
 | 
				
			||||||
 | 
					  adnsReadReg(DELTA_X_H);
 | 
				
			||||||
 | 
					  adnsReadReg(DELTA_Y_L);
 | 
				
			||||||
 | 
					  adnsReadReg(DELTA_Y_H);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (debugMode) {
 | 
					  if (debugMode) {
 | 
				
			||||||
    Serial.println(F("Uploading firmware to PMW3360"));
 | 
					    Serial.println(F("Uploading firmware to PMW3360"));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Write 0 to Rest_En bit of Config2 register to disable Rest mode.
 | 
					  // Write 0 to Rest_En bit of CONFIG2 register to disable Rest mode.
 | 
				
			||||||
  adns_write_reg(Config2, 0x00);
 | 
					  adnsWriteReg(CONFIG2, 0x00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // write 0x1d in SROM_enable reg for initializing
 | 
					  // write 0x1d in SROM_enable reg for initializing
 | 
				
			||||||
  adns_write_reg(SROM_Enable, 0x1d);
 | 
					  adnsWriteReg(SROM_ENABLE, 0x1d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // wait for more than one frame period
 | 
					  // wait for more than one frame period
 | 
				
			||||||
  // assume that the frame rate is as low as 100fps, even if it should never be that low
 | 
					  // assume that the frame rate is as low as 100fps, even if it should never be that low
 | 
				
			||||||
  delay(10);
 | 
					  delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // write 0x18 to SROM_enable to start SROM download
 | 
					  // write 0x18 to SROM_enable to start SROM download
 | 
				
			||||||
  adns_write_reg(SROM_Enable, 0x18);
 | 
					  adnsWriteReg(SROM_ENABLE, 0x18);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // write burst destination adress
 | 
					  // write burst destination adress
 | 
				
			||||||
  adns_com_begin();
 | 
					  adnsComBegin();
 | 
				
			||||||
  SPI.transfer(SROM_Load_Burst | 0x80);
 | 
					  SPI.transfer(SROM_LOAD_BURST | 0x80);
 | 
				
			||||||
  delayMicroseconds(15);
 | 
					  delayMicroseconds(15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned char c;
 | 
					  unsigned char c;
 | 
				
			||||||
| 
						 | 
					@ -259,68 +316,24 @@ void adns_upload_firmware() {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Read the SROM_ID register to verify the ID before any other register reads or writes.
 | 
					  // Read the SROM_ID register to verify the ID before any other register reads or writes.
 | 
				
			||||||
  adns_read_reg(SROM_ID);
 | 
					  adnsReadReg(SROM_ID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Write 0x00 (rest disable) to Config2 register for wired mouse.
 | 
					  // Write 0x00 (rest disable) to CONFIG2 register for wired mouse.
 | 
				
			||||||
  // (If this were a wireless design, it'd be 0x20.)
 | 
					  // (If this were a wireless design, it'd be 0x20.)
 | 
				
			||||||
  adns_write_reg(Config2, 0x00);
 | 
					  adnsWriteReg(CONFIG2, 0x00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  adns_com_end();
 | 
					  adnsComEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (debugMode) {
 | 
					  if (debugMode) {
 | 
				
			||||||
    Serial.println(F("Firmware successfully written to PMW3360"));
 | 
					    Serial.println(F("Firmware successfully written to PMW3360"));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setCPI(int cpi) {
 | 
					 | 
				
			||||||
  int cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  adns_com_begin();
 | 
					 | 
				
			||||||
  adns_write_reg(Config1, cpival);
 | 
					 | 
				
			||||||
  adns_com_end();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (debugMode) {
 | 
					 | 
				
			||||||
    Serial.print(F("Got "));
 | 
					 | 
				
			||||||
    Serial.println(cpi);
 | 
					 | 
				
			||||||
    Serial.print(F("Set cpi to "));
 | 
					 | 
				
			||||||
    Serial.println((cpival + 1) * 100);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void performStartup(void) {
 | 
					 | 
				
			||||||
  // Hard reset. Start by ensuring that the serial port is reset.
 | 
					 | 
				
			||||||
  adns_com_end();
 | 
					 | 
				
			||||||
  adns_com_begin();
 | 
					 | 
				
			||||||
  adns_com_end();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Shutdown the PMW3360, in case the microcontroller reset but the sensor didn't.
 | 
					 | 
				
			||||||
  adns_write_reg(Shutdown, 0xb6);
 | 
					 | 
				
			||||||
  delay(300);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Drop and raise SENSOR_CS to reset the spi port
 | 
					 | 
				
			||||||
  adns_com_begin();
 | 
					 | 
				
			||||||
  delayMicroseconds(40);
 | 
					 | 
				
			||||||
  adns_com_end();
 | 
					 | 
				
			||||||
  delayMicroseconds(40);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Force a reset of the PMW3360.
 | 
					 | 
				
			||||||
  adns_write_reg(Power_Up_Reset, 0x5a);
 | 
					 | 
				
			||||||
  delay(50);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Read registers 0x02 through 0x06 (and discard the data)
 | 
					 | 
				
			||||||
  adns_read_reg(Motion);
 | 
					 | 
				
			||||||
  adns_read_reg(Delta_X_L);
 | 
					 | 
				
			||||||
  adns_read_reg(Delta_X_H);
 | 
					 | 
				
			||||||
  adns_read_reg(Delta_Y_L);
 | 
					 | 
				
			||||||
  adns_read_reg(Delta_Y_H);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  adns_upload_firmware();
 | 
					 | 
				
			||||||
  delay(10);
 | 
					  delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setCPI(CPI);
 | 
					  setCPI(CPI);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // start burst mode
 | 
					  // start burst mode
 | 
				
			||||||
  adns_write_reg(Motion_Burst, 0x00);
 | 
					  adnsWriteReg(MOTION_BURST, 0x00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (debugMode) {
 | 
					  if (debugMode) {
 | 
				
			||||||
    Serial.println(F("PMW3360 successfully initialized"));
 | 
					    Serial.println(F("PMW3360 successfully initialized"));
 | 
				
			||||||
| 
						 | 
					@ -328,7 +341,7 @@ void performStartup(void) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void check_button_state() {
 | 
					void checkButtonState() {
 | 
				
			||||||
  if (!initComplete)
 | 
					  if (!initComplete)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -355,22 +368,82 @@ void check_button_state() {
 | 
				
			||||||
      // Either the button is being released, or the debounce time elapsed.
 | 
					      // Either the button is being released, or the debounce time elapsed.
 | 
				
			||||||
      AdvMouse.release_(buttonKey[i]);
 | 
					      AdvMouse.release_(buttonKey[i]);
 | 
				
			||||||
      buttonState[i] = false;
 | 
					      buttonState[i] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (buttonPin[i] == MOUSE_MIDDLE_PIN) {
 | 
				
			||||||
 | 
					        middleClickRelease = micros();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signed char moveWheel() {
 | 
				
			||||||
 | 
					  // If the mouse wheel was just released, do not scroll.
 | 
				
			||||||
 | 
					  unsigned long elapsed = micros() - middleClickRelease;
 | 
				
			||||||
 | 
					  if (elapsed < SCROLL_BUTT_DEBOUNCE) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Limit the number of scrolls per unit time.
 | 
				
			||||||
 | 
					  elapsed = micros() - lastScroll;
 | 
				
			||||||
 | 
					  if (elapsed < SCROLL_DEBOUNCE) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Don't scroll if the middle button is depressed.
 | 
				
			||||||
 | 
					  int middleButtonPin = digitalRead(MOUSE_MIDDLE_PIN);
 | 
				
			||||||
 | 
					  if (middleButtonPin == LOW) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  lastScroll = micros();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  int d1 = analogRead(OPT_ENC_PIN1);
 | 
				
			||||||
 | 
					  int d2 = analogRead(OPT_ENC_PIN2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (debugMode) {
 | 
				
			||||||
 | 
					    Serial.print(F("d1: "));
 | 
				
			||||||
 | 
					    Serial.print(d1);
 | 
				
			||||||
 | 
					    Serial.print(F(", d2: "));
 | 
				
			||||||
 | 
					    Serial.println(d2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  signed char ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (d1 < OPT_LOW_THRESHOLD && d2 < OPT_LOW_THRESHOLD) {
 | 
				
			||||||
 | 
					    if (firstOptLowPin == OPT_ENC_PIN1) {
 | 
				
			||||||
 | 
					      // scroll down
 | 
				
			||||||
 | 
					      ret = -1;
 | 
				
			||||||
 | 
					    } else if (firstOptLowPin == OPT_ENC_PIN2) {
 | 
				
			||||||
 | 
					      // scroll up
 | 
				
			||||||
 | 
					      ret = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    firstOptLowPin = 0;
 | 
				
			||||||
 | 
					  } else if (d1 < OPT_LOW_THRESHOLD) {
 | 
				
			||||||
 | 
					    firstOptLowPin = OPT_ENC_PIN1;
 | 
				
			||||||
 | 
					  } else if (d2 < OPT_LOW_THRESHOLD) {
 | 
				
			||||||
 | 
					    firstOptLowPin = OPT_ENC_PIN2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void loop() {
 | 
					void loop() {
 | 
				
			||||||
 | 
					  if (wdtMode) {
 | 
				
			||||||
 | 
					    wdt_reset();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  byte burstBuffer[12];
 | 
					  byte burstBuffer[12];
 | 
				
			||||||
  unsigned long elapsed = micros() - lastTS;
 | 
					  unsigned long elapsed = micros() - lastTS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  check_button_state();
 | 
					  checkButtonState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // polling interval : more than > 0.5 ms.
 | 
					  // polling interval : more than > 0.5 ms.
 | 
				
			||||||
  if (elapsed > 870) { // 870...whut?
 | 
					  if (elapsed > 870) { // 870...whut?
 | 
				
			||||||
    adns_com_begin();
 | 
					    adnsComBegin();
 | 
				
			||||||
    SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE3));
 | 
					    SPI.beginTransaction(SPISettings(SPIMAXIMUMSPEED, MSBFIRST, SPI_MODE3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SPI.transfer(Motion_Burst);
 | 
					    SPI.transfer(MOTION_BURST);
 | 
				
			||||||
    // Wait for tSRAD
 | 
					    // Wait for tSRAD
 | 
				
			||||||
    delayMicroseconds(35);
 | 
					    delayMicroseconds(35);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -400,7 +473,7 @@ void loop() {
 | 
				
			||||||
    dx -= xPrime;
 | 
					    dx -= xPrime;
 | 
				
			||||||
    dy += yPrime;
 | 
					    dy += yPrime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    adns_com_end();
 | 
					    adnsComEnd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    signed char wheel = moveWheel();
 | 
					    signed char wheel = moveWheel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -414,28 +487,3 @@ void loop() {
 | 
				
			||||||
    lastTS = micros();
 | 
					    lastTS = micros();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
signed char moveWheel() {
 | 
					 | 
				
			||||||
  int d1 = analogRead(OPT_ENC_PIN1);
 | 
					 | 
				
			||||||
  int d2 = analogRead(OPT_ENC_PIN2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  signed char ret = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (d1 < OPT_LOW_THRESHOLD && d2 < OPT_LOW_THRESHOLD) {
 | 
					 | 
				
			||||||
    if (firstOptLowPin == OPT_ENC_PIN1) {
 | 
					 | 
				
			||||||
      // scroll up
 | 
					 | 
				
			||||||
      ret = 1;
 | 
					 | 
				
			||||||
    } else if (firstOptLowPin == OPT_ENC_PIN2) {
 | 
					 | 
				
			||||||
      // scroll down
 | 
					 | 
				
			||||||
      ret = -1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    firstOptLowPin = 0;
 | 
					 | 
				
			||||||
  } else if (d1 < OPT_LOW_THRESHOLD) {
 | 
					 | 
				
			||||||
    firstOptLowPin = OPT_ENC_PIN1;
 | 
					 | 
				
			||||||
  } else if (d2 < OPT_LOW_THRESHOLD) {
 | 
					 | 
				
			||||||
    firstOptLowPin = OPT_ENC_PIN2;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue