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

Fork of ADNS9500 by Chris Majoros

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers adns9500.hpp Source File

adns9500.hpp

00001 /*
00002  * adns9500.hpp - Interface to access to Avago ADNS-9500 laser mouse sensors
00003  *
00004  *   Copyright 2012 Jesus Torres <jmtorres@ull.es>
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018  
00019 #ifndef ADNS9500_HPP_
00020 #define ADNS9500_HPP_
00021 
00022 #include <mbed.h>
00023 #include <stdint.h>
00024 #include <string>
00025 #include "adns9500_firmware.hpp"
00026 
00027 #define ADNS9500_CONFIGURATION_II_RPT_MOD   (1 << 2)
00028 #define ADNS9500_CONFIGURATION_IV_SROM_SIZE (1 << 1)
00029 #define ADNS9500_LASER_CTRL0_FORCE_DISABLED (1 << 0)
00030 #define ADNS9500_OBSERVATION_CHECK_BITS     0x3f
00031 
00032 #define ADNS9500_IF_MOTION(x)               (bool)(x & 0x80)
00033 #define ADNS9500_IF_LASER_FAULT(x)          (bool)(x & 0x40)
00034 #define ADNS9500_IF_RUNNING_SROM_CODE(x)    (bool)(x & 0x80)
00035 #define ADNS9500_IF_FRAME_FIRST_PIXEL(x)    (bool)(x & 0x01)
00036 #define ADNS9500_IF_OBSERVATION_TEST(x)     (bool)(x & ADNS9500_OBSERVATION_CHECK_BITS)
00037 #define ADNS9500_UINT16(ub, lb)             (uint16_t)(((ub & 0xff) << 8) | (lb & 0xff))
00038 #define ADNS9500_INT16(ub, lb)              (int16_t)(((ub & 0xff) << 8) | (lb & 0xff))
00039 
00040 #define BYTETOBINARYPATTERN "%d%d%d%d%d%d%d%d"
00041 #define BYTETOBINARY(byte)  \
00042   (byte & 0x80 ? 1 : 0), \
00043   (byte & 0x40 ? 1 : 0), \
00044   (byte & 0x20 ? 1 : 0), \
00045   (byte & 0x10 ? 1 : 0), \
00046   (byte & 0x08 ? 1 : 0), \
00047   (byte & 0x04 ? 1 : 0), \
00048   (byte & 0x02 ? 1 : 0), \
00049   (byte & 0x01 ? 1 : 0) 
00050 
00051 namespace adns9500
00052 {
00053     // Maximum SPI clock frequency supported by the sensor
00054     const int MAX_SPI_FREQUENCY = 2000000;
00055     
00056     // Internal oscillator norminal frequency
00057     const int INTERNAL_OSCILLATOR_FREQUENCY = 47000000;
00058     
00059     // Number of pixels per frame
00060     const int NUMBER_OF_PIXELS_PER_FRAME = 900;
00061     
00062     // Maximum surface quality
00063     const int MAX_SURFACE_QUALITY = 676;    // 169 * 4
00064 
00065     //
00066     // Sensor registers
00067     //
00068     
00069     enum Register
00070     {
00071         PRODUCT_ID         = 0x00,
00072         REVISION_ID        = 0x01,
00073         MOTION             = 0x02,
00074         DELTA_X_L          = 0x03,
00075         DELTA_X_H          = 0x04,
00076         DELTA_Y_L          = 0x05,
00077         DELTA_Y_H          = 0x06,
00078         SQUAL              = 0x07,
00079         PIXEL_SUM          = 0x08,
00080         MAXIMUM_PIXEL      = 0x09,
00081         MINIMUM_PIXEL      = 0x0a,
00082         SHUTTER_LOWER      = 0x0b,
00083         SHUTTER_UPPER      = 0x0c,
00084         FRAME_PERIOD_LOWER = 0x0d,
00085         FRAME_PERIOD_UPPER = 0x0e,
00086         CONFIGURATION_I    = 0x0f,
00087         CONFIGURATION_II   = 0x10,
00088         FRAME_CAPTURE      = 0x12,
00089         SROM_ENABLE        = 0x13,
00090         LASER_CTRL0        = 0x20,
00091         DATA_OUT_LOWER     = 0x25,
00092         DATA_OUT_UPPER     = 0x26,
00093         SROM_ID            = 0x2a,
00094         OBSERVATION        = 0x24,
00095         CONFIGURATION_V    = 0x2f,
00096         CONFIGURATION_IV   = 0x39,
00097         POWER_UP_RESET     = 0x3a,
00098         MOTION_BURST       = 0x50,
00099         SROM_LOAD_BURST    = 0x62,
00100         PIXEL_BURST        = 0x64
00101     };
00102 
00103     //
00104     // Supported resolutions
00105     //
00106 
00107     enum Resolution
00108     {
00109         CPI_90   = 0x01,
00110         CPI_1630 = 0x12,
00111         CPI_3240 = 0x24,
00112         CPI_5040 = 0x38
00113     };
00114     
00115     //
00116     // Motion burst data
00117     //
00118     
00119     struct MotionData
00120     {
00121         MotionData()
00122             : motion(0), observation(0), dx(0), dy(0), dxMM(0), dyMM(0),
00123               surfaceQuality(0), averagePixel(0), maximumPixel(0),
00124               minimumPixel(0), shutter(0), framePeriod(0)
00125         {}
00126     
00127         int motion;
00128         int observation;
00129         int dx;
00130         int dy;
00131         float dxMM;
00132         float dyMM;
00133         int surfaceQuality;
00134         float averagePixel;
00135         int maximumPixel;
00136         int minimumPixel;
00137         int shutter;
00138         int framePeriod;
00139     };
00140 
00141     //
00142     // Interface to access to ADNS-9500 mouse sensor
00143     //
00144 
00145     class ADNS9500
00146     {
00147         public:
00148         
00149             //
00150             // Create the sensor interface
00151             //
00152             // @param mosi MOSI pin for the SPI interface
00153             // @param miso MISO pin for the SPI interface
00154             // @param sclk SCLK pin for the SPI interface
00155             // @param spi_frequency SPI clock frequency in Hz up to MAX_SPI_PORT_FREQUENCY
00156             // @param ncs A digital active-low output pin for sensor chip select
00157             // @param motion A digital active-low input pin activated by the sensor when motion
00158             //               is detected
00159             //
00160             ADNS9500(PinName mosi, PinName miso, PinName sclk, PinName ncs,
00161                 int spi_frequency = MAX_SPI_FREQUENCY, PinName motion = NC);
00162 
00163             //
00164             // Destroy de sensor interface
00165             //
00166             ~ADNS9500();
00167 
00168             //
00169             // Power up/reset the sensor
00170             // Terminate with error if the connection can not be established
00171             //
00172             // @param firmware If the firmware has to be downloaded, C-string containing the name
00173             //                 of the file where it is stored, or NULL in other case
00174             //
00175             void reset(const uint8_t* fw = NULL, uint16_t fw_len = 0 );
00176 
00177             //
00178             // Shutdown the sensor
00179             //
00180             void shutdown();
00181 
00182             //
00183             // Read the value of a sensor register
00184             //
00185             // @param lregister The register which to read its value
00186             // @return The value of the register
00187             //
00188             int read(Register lregister);
00189             
00190             //
00191             // Read the values of sensor registers
00192             //
00193             // @param uregister The register which to read the upper byte
00194             // @param lregister The register which to read the lower byte
00195             // @return The values of registers as a 16-bit integer, putting the value
00196             //         of uregister in the upper byte and the value of lregister in the
00197             //         lower byte
00198             //
00199             int read(Register uregister, Register lregister);
00200 
00201             //
00202             // Get information about sensor status
00203             //
00204             // @return The value of MOTION register. It tells if motion or laser fault
00205             //         conditions have ocurred, laser power setting status and operating
00206             //         mode in current frame
00207             //
00208             int status()
00209                 { return read(MOTION); }
00210            
00211             //
00212             // Download the firmware to the sensor SROM
00213             //
00214             // @param filename The name of the file which contains the sensor firmware
00215             // @return The SROM CRC value
00216             //
00217             int sromDownload(const uint8_t*, uint16_t);
00218 
00219             //
00220             // Enable the laser
00221             //
00222             // @param enable True if laser must be enabled, or false if laser must be disabled
00223             //
00224             void enableLaser(bool enable=true);
00225             void getLaser(void);
00226 
00227             //
00228             // Get motion deltas from sensor
00229             //
00230             // @param dx The component X of displacement
00231             // @param dy The component Y of displacement
00232             // @return True if motion was occurred since the last time the function was called,
00233             //         or false in other case
00234             //
00235             bool getMotionDelta(int16_t& dx, int16_t& dy);
00236 
00237             //
00238             // Get motion deltas in mm. from sensor
00239             //
00240             // @param dx The component X of displacement in mm.
00241             // @param dy The component Y of displacement in mm.
00242             // @return True if motion was occurred since the last time the function was called,
00243             //         or false in other case
00244             //
00245             bool getMotionDeltaMM(float& dx, float& dy);
00246             
00247             //
00248             // Get all information about motion
00249             //
00250             // @param data The struct where sensor data will be stored
00251             // @return True if motion was occurred since the last time the function was called,
00252             //         or false in other case
00253             //
00254             bool getMotionData(MotionData& data);
00255 
00256             //
00257             // Set the resolution on XY axes together
00258             //
00259             // @param xy_resolution The resolution for X-axis and Y-axis
00260             //
00261             void setResolution( uint16_t xy_resolution);
00262 
00263             //
00264             // Set the resolutions on X-axis and Y-axis
00265             //
00266             // @param x_resolution The resolution for X-axis
00267             // @param y_resolution The resolution for Y-axis
00268             //
00269             void setResolution(uint16_t x_resolution, uint16_t y_resolution);
00270 
00271             //
00272             // Get a full array of pixel values from a single frame.
00273             // This disables navigation and overwrites any donwloaded firmware,
00274             // so call to reset() is needed to restore them
00275             //
00276             // @param pixels A pointer to the array where pixel values will be stored
00277             //
00278             void captureFrame(uint8_t* pixels);
00279 
00280             //
00281             // Member function invoked when motion has ocurred and if a motion pin
00282             // was specified when the object constructor was called.
00283             // By default it invokes the function specified by a previous call to attach()
00284             //
00285             virtual void motionTrigger()
00286                 { motionTrigger_.call(); }
00287 
00288             //
00289             // Attach a function to call when a falling edge occurs on motion pin
00290             //
00291             // @param function A pointer to a function or 0 to set the attached function as none
00292             //
00293             void attach(void (*function)(void))
00294                 { motionTrigger_.attach(function); }
00295 
00296             //
00297             // Attach a member function to call when a falling edge occurs on motion pin
00298             //
00299             // @param object A reference to the object to call the member function on
00300             // @param function A pointer to the member function to be called
00301             //
00302             template<typename T>
00303             void attach(T& object, void (T::*member)(void))
00304                 { motionTrigger_.attach(object, member); }
00305 
00306             int cpi_to_res( uint16_t cpi ){
00307                 int res = cpi / 90;
00308         
00309                 if( res < 0x01 ){
00310                     res = 0x01;
00311                 }
00312                 else if( res > 0x38 ){
00313                     res = 0x38;
00314                 }
00315                 return res;
00316             }
00317             
00318         private:
00319             SPI spi_;
00320             InterruptIn motion_;
00321             DigitalOut ncs_;
00322 
00323             bool enabled_;            
00324             int xCpi_, yCpi_;
00325             
00326             FunctionPointer motionTrigger_;
00327             
00328             //
00329             // Write a byte to the specified register
00330             //
00331             // @param address The register address
00332             // @param value The value to be written to the register
00333             //
00334             void spiSend(Register address, int value);
00335 
00336             //
00337             // Read a byte from the specified register
00338             //
00339             // @param address The register address
00340             // @return The value of the register
00341             //
00342             int spiReceive(Register address);
00343     };
00344 }
00345 
00346 #endif /* ADNS9500_HPP_ */