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

Dependencies:   mbed

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