Interface to access to Avago ADNS-9500 laser mouse sensors.

Dependencies:   mbed

Committer:
aplatanado
Date:
Thu Mar 22 15:04:33 2012 +0000
Revision:
2:ee0c13ef1320
Parent:
1:fa3052be61b5
Child:
3:898ed1944119
Fix motion burst

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aplatanado 0:782f2061a8f5 1 /*
aplatanado 1:fa3052be61b5 2 * adns9500.hpp - Interface to access to Avago ADNS-9500 laser mouse sensors
aplatanado 0:782f2061a8f5 3 *
aplatanado 0:782f2061a8f5 4 * Copyright 2012 Jesus Torres <jmtorres@ull.es>
aplatanado 0:782f2061a8f5 5 *
aplatanado 0:782f2061a8f5 6 * Licensed under the Apache License, Version 2.0 (the "License");
aplatanado 0:782f2061a8f5 7 * you may not use this file except in compliance with the License.
aplatanado 0:782f2061a8f5 8 * You may obtain a copy of the License at
aplatanado 0:782f2061a8f5 9 *
aplatanado 0:782f2061a8f5 10 * http://www.apache.org/licenses/LICENSE-2.0
aplatanado 0:782f2061a8f5 11 *
aplatanado 0:782f2061a8f5 12 * Unless required by applicable law or agreed to in writing, software
aplatanado 0:782f2061a8f5 13 * distributed under the License is distributed on an "AS IS" BASIS,
aplatanado 0:782f2061a8f5 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
aplatanado 0:782f2061a8f5 15 * See the License for the specific language governing permissions and
aplatanado 0:782f2061a8f5 16 * limitations under the License.
aplatanado 0:782f2061a8f5 17 */
aplatanado 0:782f2061a8f5 18
aplatanado 0:782f2061a8f5 19 #ifndef ADNS9500_HPP_
aplatanado 0:782f2061a8f5 20 #define ADNS9500_HPP_
aplatanado 0:782f2061a8f5 21
aplatanado 0:782f2061a8f5 22 #include <mbed.h>
aplatanado 0:782f2061a8f5 23 #include <stdint.h>
aplatanado 0:782f2061a8f5 24 #include <string>
aplatanado 0:782f2061a8f5 25
aplatanado 0:782f2061a8f5 26 #define ADNS9500_CONFIGURATION_II_RPT_MOD (1 << 2)
aplatanado 0:782f2061a8f5 27 #define ADNS9500_CONFIGURATION_IV_SROM_SIZE (1 << 1)
aplatanado 0:782f2061a8f5 28 #define ADNS9500_LASER_CTRL0_FORCE_DISABLED (1 << 0)
aplatanado 0:782f2061a8f5 29 #define ADNS9500_OBSERVATION_CHECK_BITS 0x3f
aplatanado 0:782f2061a8f5 30
aplatanado 0:782f2061a8f5 31 #define ADNS9500_IF_MOTION(x) (bool)(x & 0x80)
aplatanado 0:782f2061a8f5 32 #define ADNS9500_IF_LASER_FAULT(x) (bool)(x & 0x40)
aplatanado 0:782f2061a8f5 33 #define ADNS9500_IF_RUNNING_SROM_CODE(x) (bool)(x & 0x80)
aplatanado 0:782f2061a8f5 34 #define ADNS9500_IF_OBSERVATION_TEST(x) (bool)(x & ADNS9500_OBSERVATION_CHECK_BITS)
aplatanado 2:ee0c13ef1320 35 #define ADNS9500_UINT16(ub, lb) (((uint16_t)ub << 8) + (uint16_t)lb)
aplatanado 2:ee0c13ef1320 36 #define ADNS9500_INT16(ub, lb) ((((int16_t)(int8_t)ub) << 8) + (int16_t)lb)
aplatanado 0:782f2061a8f5 37
aplatanado 0:782f2061a8f5 38 namespace adns9500
aplatanado 0:782f2061a8f5 39 {
aplatanado 0:782f2061a8f5 40 // Maximum SPI clock frequency supported by the sensor
aplatanado 2:ee0c13ef1320 41 const int MAX_SPI_FREQUENCY = 200;
aplatanado 0:782f2061a8f5 42
aplatanado 0:782f2061a8f5 43 // Internal oscillator norminal frequency
aplatanado 0:782f2061a8f5 44 const int INTERNAL_OSCILLATOR_FREQUENCY = 47000000;
aplatanado 0:782f2061a8f5 45
aplatanado 0:782f2061a8f5 46 // Number of pixels per frame
aplatanado 0:782f2061a8f5 47 const int NUMBER_OF_PIXELS_PER_FRAME = 900;
aplatanado 2:ee0c13ef1320 48
aplatanado 2:ee0c13ef1320 49 // Maximum surface quality
aplatanado 2:ee0c13ef1320 50 const int MAX_SURFACE_QUALITY = 676; // 169 * 4
aplatanado 0:782f2061a8f5 51
aplatanado 0:782f2061a8f5 52 //
aplatanado 0:782f2061a8f5 53 // Sensor registers
aplatanado 0:782f2061a8f5 54 //
aplatanado 0:782f2061a8f5 55
aplatanado 0:782f2061a8f5 56 enum Register
aplatanado 0:782f2061a8f5 57 {
aplatanado 0:782f2061a8f5 58 PRODUCT_ID = 0x00,
aplatanado 0:782f2061a8f5 59 REVISION_ID = 0x01,
aplatanado 0:782f2061a8f5 60 MOTION = 0x02,
aplatanado 0:782f2061a8f5 61 DELTA_X_L = 0x03,
aplatanado 0:782f2061a8f5 62 DELTA_X_H = 0x04,
aplatanado 0:782f2061a8f5 63 DELTA_Y_L = 0x05,
aplatanado 0:782f2061a8f5 64 DELTA_Y_H = 0x06,
aplatanado 0:782f2061a8f5 65 SQUAL = 0x07,
aplatanado 0:782f2061a8f5 66 PIXEL_SUM = 0x08,
aplatanado 0:782f2061a8f5 67 MAXIMUM_PIXEL = 0x09,
aplatanado 0:782f2061a8f5 68 MINIMUM_PIXEL = 0x0a,
aplatanado 0:782f2061a8f5 69 SHUTTER_LOWER = 0x0b,
aplatanado 0:782f2061a8f5 70 SHUTTER_UPPER = 0x0c,
aplatanado 0:782f2061a8f5 71 FRAME_PERIOD_LOWER = 0x0d,
aplatanado 0:782f2061a8f5 72 FRAME_PERIOD_UPPER = 0x0e,
aplatanado 0:782f2061a8f5 73 CONFIGURATION_I = 0x0f,
aplatanado 0:782f2061a8f5 74 CONFIGURATION_II = 0x10,
aplatanado 0:782f2061a8f5 75 FRAME_CAPTURE = 0x12,
aplatanado 0:782f2061a8f5 76 SROM_ENABLE = 0x13,
aplatanado 0:782f2061a8f5 77 LASER_CTRL0 = 0x20,
aplatanado 0:782f2061a8f5 78 DATA_OUT_LOWER = 0x25,
aplatanado 0:782f2061a8f5 79 DATA_OUT_UPPER = 0x26,
aplatanado 0:782f2061a8f5 80 SROM_ID = 0x2a,
aplatanado 0:782f2061a8f5 81 OBSERVATION = 0x24,
aplatanado 0:782f2061a8f5 82 CONFIGURATION_V = 0x2f,
aplatanado 0:782f2061a8f5 83 CONFIGURATION_IV = 0x39,
aplatanado 0:782f2061a8f5 84 POWER_UP_RESET = 0x3a,
aplatanado 0:782f2061a8f5 85 MOTION_BURST = 0x50,
aplatanado 0:782f2061a8f5 86 SROM_LOAD_BURST = 0x62,
aplatanado 0:782f2061a8f5 87 PIXEL_BURST = 0x62
aplatanado 0:782f2061a8f5 88 };
aplatanado 0:782f2061a8f5 89
aplatanado 0:782f2061a8f5 90 //
aplatanado 0:782f2061a8f5 91 // Supported resolutions
aplatanado 0:782f2061a8f5 92 //
aplatanado 0:782f2061a8f5 93
aplatanado 0:782f2061a8f5 94 enum Resolution
aplatanado 0:782f2061a8f5 95 {
aplatanado 0:782f2061a8f5 96 CPI_90 = 0x01,
aplatanado 0:782f2061a8f5 97 CPI_1630 = 0x12,
aplatanado 0:782f2061a8f5 98 CPI_3240 = 0x24,
aplatanado 0:782f2061a8f5 99 CPI_5040 = 0x38
aplatanado 0:782f2061a8f5 100 };
aplatanado 0:782f2061a8f5 101
aplatanado 0:782f2061a8f5 102 //
aplatanado 0:782f2061a8f5 103 // Motion burst data
aplatanado 0:782f2061a8f5 104 //
aplatanado 0:782f2061a8f5 105
aplatanado 0:782f2061a8f5 106 struct MotionData
aplatanado 0:782f2061a8f5 107 {
aplatanado 2:ee0c13ef1320 108 MotionData()
aplatanado 2:ee0c13ef1320 109 : motion(0), observation(0), dx(0), dy(0), dxMM(0), dyMM(0),
aplatanado 2:ee0c13ef1320 110 surfaceQuality(0), averagePixel(0), maximumPixel(0),
aplatanado 2:ee0c13ef1320 111 minimumPixel(0), shutter(0), framePeriod(0)
aplatanado 2:ee0c13ef1320 112 {}
aplatanado 2:ee0c13ef1320 113
aplatanado 0:782f2061a8f5 114 int motion;
aplatanado 0:782f2061a8f5 115 int observation;
aplatanado 0:782f2061a8f5 116 int dx;
aplatanado 0:782f2061a8f5 117 int dy;
aplatanado 2:ee0c13ef1320 118 float dxMM;
aplatanado 2:ee0c13ef1320 119 float dyMM;
aplatanado 2:ee0c13ef1320 120 int surfaceQuality;
aplatanado 2:ee0c13ef1320 121 float averagePixel;
aplatanado 0:782f2061a8f5 122 int maximumPixel;
aplatanado 0:782f2061a8f5 123 int minimumPixel;
aplatanado 0:782f2061a8f5 124 int shutter;
aplatanado 0:782f2061a8f5 125 int framePeriod;
aplatanado 0:782f2061a8f5 126 };
aplatanado 0:782f2061a8f5 127
aplatanado 0:782f2061a8f5 128 //
aplatanado 0:782f2061a8f5 129 // Interface to access to ADNS-9500 mouse sensor
aplatanado 0:782f2061a8f5 130 //
aplatanado 0:782f2061a8f5 131
aplatanado 0:782f2061a8f5 132 class ADNS9500
aplatanado 0:782f2061a8f5 133 {
aplatanado 0:782f2061a8f5 134 public:
aplatanado 0:782f2061a8f5 135
aplatanado 0:782f2061a8f5 136 //
aplatanado 0:782f2061a8f5 137 // Create the sensor interface
aplatanado 0:782f2061a8f5 138 //
aplatanado 0:782f2061a8f5 139 // @param mosi MOSI pin for the SPI interface
aplatanado 0:782f2061a8f5 140 // @param miso MISO pin for the SPI interface
aplatanado 0:782f2061a8f5 141 // @param sclk SCLK pin for the SPI interface
aplatanado 0:782f2061a8f5 142 // @param spi_frequency SPI clock frequency in Hz up to MAX_SPI_PORT_FREQUENCY
aplatanado 0:782f2061a8f5 143 // @param ncs A digital active-low output pin for sensor chip select
aplatanado 0:782f2061a8f5 144 // @param motion A digital active-low input pin activated by the sensor when motion
aplatanado 0:782f2061a8f5 145 // is detected
aplatanado 0:782f2061a8f5 146 //
aplatanado 0:782f2061a8f5 147 ADNS9500(PinName mosi, PinName miso, PinName sclk, PinName ncs,
aplatanado 0:782f2061a8f5 148 int spi_frequency = MAX_SPI_FREQUENCY, PinName motion = NC);
aplatanado 0:782f2061a8f5 149
aplatanado 0:782f2061a8f5 150 //
aplatanado 0:782f2061a8f5 151 // Destroy de sensor interface
aplatanado 0:782f2061a8f5 152 //
aplatanado 0:782f2061a8f5 153 ~ADNS9500();
aplatanado 0:782f2061a8f5 154
aplatanado 0:782f2061a8f5 155 //
aplatanado 0:782f2061a8f5 156 // Power up/reset the sensor
aplatanado 0:782f2061a8f5 157 // Terminate with error if the connection can not be established
aplatanado 0:782f2061a8f5 158 //
aplatanado 0:782f2061a8f5 159 // @param firmware If the firmware has to be downloaded, C-string containing the name
aplatanado 0:782f2061a8f5 160 // of the file where it is stored, or NULL in other case
aplatanado 0:782f2061a8f5 161 //
aplatanado 0:782f2061a8f5 162 void reset(const char* firmware = NULL);
aplatanado 0:782f2061a8f5 163
aplatanado 0:782f2061a8f5 164 //
aplatanado 0:782f2061a8f5 165 // Shutdown the sensor
aplatanado 0:782f2061a8f5 166 //
aplatanado 0:782f2061a8f5 167 void shutdown();
aplatanado 0:782f2061a8f5 168
aplatanado 0:782f2061a8f5 169 //
aplatanado 0:782f2061a8f5 170 // Read the value of a sensor register
aplatanado 0:782f2061a8f5 171 //
aplatanado 0:782f2061a8f5 172 // @param lregister The register which to read its value
aplatanado 0:782f2061a8f5 173 // @return The value of the register
aplatanado 0:782f2061a8f5 174 //
aplatanado 0:782f2061a8f5 175 int read(Register lregister);
aplatanado 0:782f2061a8f5 176
aplatanado 0:782f2061a8f5 177 //
aplatanado 0:782f2061a8f5 178 // Read the values of sensor registers
aplatanado 0:782f2061a8f5 179 //
aplatanado 0:782f2061a8f5 180 // @param uregister The register which to read the upper byte
aplatanado 0:782f2061a8f5 181 // @param lregister The register which to read the lower byte
aplatanado 0:782f2061a8f5 182 // @return The values of registers as a 16-bit integer, putting the value
aplatanado 0:782f2061a8f5 183 // of uregister in the upper byte and the value of lregister in the
aplatanado 0:782f2061a8f5 184 // lower byte
aplatanado 0:782f2061a8f5 185 //
aplatanado 0:782f2061a8f5 186 int read(Register uregister, Register lregister);
aplatanado 0:782f2061a8f5 187
aplatanado 0:782f2061a8f5 188 //
aplatanado 0:782f2061a8f5 189 // Get information about sensor status
aplatanado 0:782f2061a8f5 190 //
aplatanado 0:782f2061a8f5 191 // @return The value of MOTION register. It tells if motion or laser fault
aplatanado 0:782f2061a8f5 192 // conditions have ocurred, laser power setting status and operating
aplatanado 0:782f2061a8f5 193 // mode in current frame
aplatanado 0:782f2061a8f5 194 //
aplatanado 0:782f2061a8f5 195 int status()
aplatanado 0:782f2061a8f5 196 { return read(MOTION); }
aplatanado 0:782f2061a8f5 197
aplatanado 0:782f2061a8f5 198 //
aplatanado 0:782f2061a8f5 199 // Download the firmware to the sensor SROM
aplatanado 0:782f2061a8f5 200 //
aplatanado 0:782f2061a8f5 201 // @param filename The name of the file which contains the sensor firmware
aplatanado 0:782f2061a8f5 202 // @return The SROM CRC value
aplatanado 0:782f2061a8f5 203 //
aplatanado 0:782f2061a8f5 204 int sromDownload(const char* filename);
aplatanado 0:782f2061a8f5 205
aplatanado 0:782f2061a8f5 206 //
aplatanado 0:782f2061a8f5 207 // Enable the laser
aplatanado 0:782f2061a8f5 208 //
aplatanado 0:782f2061a8f5 209 // @param enable True if laser must be enabled, or false if laser must be disabled
aplatanado 0:782f2061a8f5 210 //
aplatanado 0:782f2061a8f5 211 void enableLaser(bool enable=true);
aplatanado 0:782f2061a8f5 212
aplatanado 0:782f2061a8f5 213 //
aplatanado 0:782f2061a8f5 214 // Get motion deltas from sensor
aplatanado 0:782f2061a8f5 215 //
aplatanado 0:782f2061a8f5 216 // @param dx The component X of displacement
aplatanado 0:782f2061a8f5 217 // @param dy The component Y of displacement
aplatanado 0:782f2061a8f5 218 // @return True if motion was occurred since the last time the function was called,
aplatanado 0:782f2061a8f5 219 // or false in other case
aplatanado 0:782f2061a8f5 220 //
aplatanado 0:782f2061a8f5 221 bool getMotionDelta(int& dx, int& dy);
aplatanado 0:782f2061a8f5 222
aplatanado 0:782f2061a8f5 223 //
aplatanado 0:782f2061a8f5 224 // Get motion deltas in mm. from sensor
aplatanado 0:782f2061a8f5 225 //
aplatanado 0:782f2061a8f5 226 // @param dx The component X of displacement in mm.
aplatanado 0:782f2061a8f5 227 // @param dy The component Y of displacement in mm.
aplatanado 0:782f2061a8f5 228 // @return True if motion was occurred since the last time the function was called,
aplatanado 0:782f2061a8f5 229 // or false in other case
aplatanado 0:782f2061a8f5 230 //
aplatanado 0:782f2061a8f5 231 bool getMotionDeltaMM(float& dx, float& dy);
aplatanado 0:782f2061a8f5 232
aplatanado 0:782f2061a8f5 233 //
aplatanado 0:782f2061a8f5 234 // Get all information about motion
aplatanado 0:782f2061a8f5 235 //
aplatanado 0:782f2061a8f5 236 // @param data The struct where sensor data will be stored
aplatanado 0:782f2061a8f5 237 // @return True if motion was occurred since the last time the function was called,
aplatanado 0:782f2061a8f5 238 // or false in other case
aplatanado 0:782f2061a8f5 239 //
aplatanado 0:782f2061a8f5 240 bool getMotionData(MotionData& data);
aplatanado 0:782f2061a8f5 241
aplatanado 0:782f2061a8f5 242 //
aplatanado 0:782f2061a8f5 243 // Set the resolution on XY axes together
aplatanado 0:782f2061a8f5 244 //
aplatanado 0:782f2061a8f5 245 // @param xy_resolution The resolution for X-axis and Y-axis
aplatanado 0:782f2061a8f5 246 //
aplatanado 0:782f2061a8f5 247 void setResolution(Resolution xy_resolution);
aplatanado 0:782f2061a8f5 248
aplatanado 0:782f2061a8f5 249 //
aplatanado 0:782f2061a8f5 250 // Set the resolutions on X-axis and Y-axis
aplatanado 0:782f2061a8f5 251 //
aplatanado 0:782f2061a8f5 252 // @param x_resolution The resolution for X-axis
aplatanado 0:782f2061a8f5 253 // @param y_resolution The resolution for Y-axis
aplatanado 0:782f2061a8f5 254 //
aplatanado 0:782f2061a8f5 255 void setResolution(Resolution x_resolution, Resolution y_resolution);
aplatanado 0:782f2061a8f5 256
aplatanado 0:782f2061a8f5 257 //
aplatanado 0:782f2061a8f5 258 // Get a full array of pixel values from a single frame.
aplatanado 0:782f2061a8f5 259 // This disables navigation and overwrites any donwloaded firmware,
aplatanado 0:782f2061a8f5 260 // so call to reset() is needed to restore them
aplatanado 0:782f2061a8f5 261 //
aplatanado 0:782f2061a8f5 262 // @param pixels The array where pixel values will be stored
aplatanado 0:782f2061a8f5 263 //
aplatanado 0:782f2061a8f5 264 void captureFrame(uint8_t pixels[NUMBER_OF_PIXELS_PER_FRAME]);
aplatanado 0:782f2061a8f5 265
aplatanado 0:782f2061a8f5 266 //
aplatanado 0:782f2061a8f5 267 // Member function invoked when motion has ocurred and if a motion pin
aplatanado 0:782f2061a8f5 268 // was specified when the object constructor was called.
aplatanado 0:782f2061a8f5 269 // By default it invokes the function specified by a previous call to attach()
aplatanado 0:782f2061a8f5 270 //
aplatanado 0:782f2061a8f5 271 virtual void motionTrigger()
aplatanado 0:782f2061a8f5 272 { motionTrigger_.call(); }
aplatanado 0:782f2061a8f5 273
aplatanado 0:782f2061a8f5 274 //
aplatanado 0:782f2061a8f5 275 // Attach a function to call when a falling edge occurs on motion pin
aplatanado 0:782f2061a8f5 276 //
aplatanado 0:782f2061a8f5 277 // @param function A pointer to a function or 0 to set the attached function as none
aplatanado 0:782f2061a8f5 278 //
aplatanado 0:782f2061a8f5 279 void attach(void (*function)(void))
aplatanado 0:782f2061a8f5 280 { motionTrigger_.attach(function); }
aplatanado 0:782f2061a8f5 281
aplatanado 0:782f2061a8f5 282 //
aplatanado 0:782f2061a8f5 283 // Attach a member function to call when a falling edge occurs on motion pin
aplatanado 0:782f2061a8f5 284 //
aplatanado 0:782f2061a8f5 285 // @param object A reference to the object to call the member function on
aplatanado 0:782f2061a8f5 286 // @param function A pointer to the member function to be called
aplatanado 0:782f2061a8f5 287 //
aplatanado 0:782f2061a8f5 288 template<typename T>
aplatanado 0:782f2061a8f5 289 void attach(T& object, void (T::*member)(void))
aplatanado 0:782f2061a8f5 290 { motionTrigger_.attach(object, member); }
aplatanado 0:782f2061a8f5 291
aplatanado 0:782f2061a8f5 292 private:
aplatanado 0:782f2061a8f5 293 SPI spi_;
aplatanado 0:782f2061a8f5 294 InterruptIn motion_;
aplatanado 0:782f2061a8f5 295 DigitalOut ncs_;
aplatanado 2:ee0c13ef1320 296
aplatanado 0:782f2061a8f5 297 bool enabled_;
aplatanado 0:782f2061a8f5 298 int xCpi_, yCpi_;
aplatanado 0:782f2061a8f5 299
aplatanado 0:782f2061a8f5 300 FunctionPointer motionTrigger_;
aplatanado 2:ee0c13ef1320 301
aplatanado 2:ee0c13ef1320 302 //
aplatanado 2:ee0c13ef1320 303 // Write a byte to the specified register
aplatanado 2:ee0c13ef1320 304 //
aplatanado 2:ee0c13ef1320 305 // @param address The register address
aplatanado 2:ee0c13ef1320 306 // @param value The value to be written to the register
aplatanado 2:ee0c13ef1320 307 //
aplatanado 2:ee0c13ef1320 308 void spiSend(Register address, int value);
aplatanado 2:ee0c13ef1320 309
aplatanado 2:ee0c13ef1320 310 //
aplatanado 2:ee0c13ef1320 311 // Read a byte from the specified register
aplatanado 2:ee0c13ef1320 312 //
aplatanado 2:ee0c13ef1320 313 // @param address The register address
aplatanado 2:ee0c13ef1320 314 // @return The value of the register
aplatanado 2:ee0c13ef1320 315 //
aplatanado 2:ee0c13ef1320 316 int spiReceive(Register address);
aplatanado 0:782f2061a8f5 317 };
aplatanado 0:782f2061a8f5 318 }
aplatanado 0:782f2061a8f5 319
aplatanado 0:782f2061a8f5 320 #endif /* ADNS9500_HPP_ */