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

Dependencies:   mbed

Revision:
1:fa3052be61b5
Parent:
0:782f2061a8f5
Child:
2:ee0c13ef1320
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adns9500.hpp	Mon Feb 13 11:39:24 2012 +0000
@@ -0,0 +1,293 @@
+/*
+ * adns9500.hpp - Interface to access to Avago ADNS-9500 laser mouse sensors
+ *
+ *   Copyright 2012 Jesus Torres <jmtorres@ull.es>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#ifndef ADNS9500_HPP_
+#define ADNS9500_HPP_
+
+#include <mbed.h>
+#include <stdint.h>
+#include <string>
+
+#define ADNS9500_CONFIGURATION_II_RPT_MOD   (1 << 2)
+#define ADNS9500_CONFIGURATION_IV_SROM_SIZE (1 << 1)
+#define ADNS9500_LASER_CTRL0_FORCE_DISABLED (1 << 0)
+#define ADNS9500_OBSERVATION_CHECK_BITS     0x3f
+
+#define ADNS9500_IF_MOTION(x)               (bool)(x & 0x80)
+#define ADNS9500_IF_LASER_FAULT(x)          (bool)(x & 0x40)
+#define ADNS9500_IF_RUNNING_SROM_CODE(x)    (bool)(x & 0x80)
+#define ADNS9500_IF_OBSERVATION_TEST(x)     (bool)(x & ADNS9500_OBSERVATION_CHECK_BITS)
+#define ADNS9500_UINT16(ub, lb)             ((uint16_t)ub << 8 | (uint16_t)lb)
+
+namespace adns9500
+{
+    // Maximum SPI clock frequency supported by the sensor
+    const int MAX_SPI_FREQUENCY = 2000000;
+    
+    // Internal oscillator norminal frequency
+    const int INTERNAL_OSCILLATOR_FREQUENCY = 47000000;
+    
+    // Number of pixels per frame
+    const int NUMBER_OF_PIXELS_PER_FRAME = 900;
+
+    //
+    // Sensor registers
+    //
+    
+    enum Register
+    {
+        PRODUCT_ID         = 0x00,
+        REVISION_ID        = 0x01,
+        MOTION             = 0x02,
+        DELTA_X_L          = 0x03,
+        DELTA_X_H          = 0x04,
+        DELTA_Y_L          = 0x05,
+        DELTA_Y_H          = 0x06,
+        SQUAL              = 0x07,
+        PIXEL_SUM          = 0x08,
+        MAXIMUM_PIXEL      = 0x09,
+        MINIMUM_PIXEL      = 0x0a,
+        SHUTTER_LOWER      = 0x0b,
+        SHUTTER_UPPER      = 0x0c,
+        FRAME_PERIOD_LOWER = 0x0d,
+        FRAME_PERIOD_UPPER = 0x0e,
+        CONFIGURATION_I    = 0x0f,
+        CONFIGURATION_II   = 0x10,
+        FRAME_CAPTURE      = 0x12,
+        SROM_ENABLE        = 0x13,
+        LASER_CTRL0        = 0x20,
+        DATA_OUT_LOWER     = 0x25,
+        DATA_OUT_UPPER     = 0x26,
+        SROM_ID            = 0x2a,
+        OBSERVATION        = 0x24,
+        CONFIGURATION_V    = 0x2f,
+        CONFIGURATION_IV   = 0x39,
+        POWER_UP_RESET     = 0x3a,
+        MOTION_BURST       = 0x50,
+        SROM_LOAD_BURST    = 0x62,
+        PIXEL_BURST        = 0x62
+    };
+
+    //
+    // Supported resolutions
+    //
+
+    enum Resolution
+    {
+        CPI_90   = 0x01,
+        CPI_1630 = 0x12,
+        CPI_3240 = 0x24,
+        CPI_5040 = 0x38
+    };
+    
+    //
+    // Motion burst data
+    //
+    
+    struct MotionData
+    {
+        int motion;
+        int observation;
+        int dx;
+        int dy;
+        int squal;
+        int pixelSum;
+        int maximumPixel;
+        int minimumPixel;
+        int shutter;
+        int framePeriod;
+    };
+
+    //
+    // Interface to access to ADNS-9500 mouse sensor
+    //
+
+    class ADNS9500
+    {
+        public:
+        
+            //
+            // Create the sensor interface
+            //
+            // @param mosi MOSI pin for the SPI interface
+            // @param miso MISO pin for the SPI interface
+            // @param sclk SCLK pin for the SPI interface
+            // @param spi_frequency SPI clock frequency in Hz up to MAX_SPI_PORT_FREQUENCY
+            // @param ncs A digital active-low output pin for sensor chip select
+            // @param motion A digital active-low input pin activated by the sensor when motion
+            //               is detected
+            //
+            ADNS9500(PinName mosi, PinName miso, PinName sclk, PinName ncs,
+                int spi_frequency = MAX_SPI_FREQUENCY, PinName motion = NC);
+
+            //
+            // Destroy de sensor interface
+            //
+            ~ADNS9500();
+
+            //
+            // Power up/reset the sensor
+            // Terminate with error if the connection can not be established
+            //
+            // @param firmware If the firmware has to be downloaded, C-string containing the name
+            //                 of the file where it is stored, or NULL in other case
+            //
+            void reset(const char* firmware = NULL);
+
+            //
+            // Shutdown the sensor
+            //
+            void shutdown();
+
+            //
+            // Read the value of a sensor register
+            //
+            // @param lregister The register which to read its value
+            // @return The value of the register
+            //
+            int read(Register lregister);
+            
+            //
+            // Read the values of sensor registers
+            //
+            // @param uregister The register which to read the upper byte
+            // @param lregister The register which to read the lower byte
+            // @return The values of registers as a 16-bit integer, putting the value
+            //         of uregister in the upper byte and the value of lregister in the
+            //         lower byte
+            //
+            int read(Register uregister, Register lregister);
+
+            //
+            // Get information about sensor status
+            //
+            // @return The value of MOTION register. It tells if motion or laser fault
+            //         conditions have ocurred, laser power setting status and operating
+            //         mode in current frame
+            //
+            int status()
+                { return read(MOTION); }
+           
+            //
+            // Download the firmware to the sensor SROM
+            //
+            // @param filename The name of the file which contains the sensor firmware
+            // @return The SROM CRC value
+            //
+            int sromDownload(const char* filename);
+
+            //
+            // Enable the laser
+            //
+            // @param enable True if laser must be enabled, or false if laser must be disabled
+            //
+            void enableLaser(bool enable=true);
+
+            //
+            // Get motion deltas from sensor
+            //
+            // @param dx The component X of displacement
+            // @param dy The component Y of displacement
+            // @return True if motion was occurred since the last time the function was called,
+            //         or false in other case
+            //
+            bool getMotionDelta(int& dx, int& dy);
+
+            //
+            // Get motion deltas in mm. from sensor
+            //
+            // @param dx The component X of displacement in mm.
+            // @param dy The component Y of displacement in mm.
+            // @return True if motion was occurred since the last time the function was called,
+            //         or false in other case
+            //
+            bool getMotionDeltaMM(float& dx, float& dy);
+            
+            //
+            // Get all information about motion
+            //
+            // @param data The struct where sensor data will be stored
+            // @return True if motion was occurred since the last time the function was called,
+            //         or false in other case
+            //
+            bool getMotionData(MotionData& data);
+
+            //
+            // Set the resolution on XY axes together
+            //
+            // @param xy_resolution The resolution for X-axis and Y-axis
+            //
+            void setResolution(Resolution xy_resolution);
+
+            //
+            // Set the resolutions on X-axis and Y-axis
+            //
+            // @param x_resolution The resolution for X-axis
+            // @param y_resolution The resolution for Y-axis
+            //
+            void setResolution(Resolution x_resolution, Resolution y_resolution);
+
+            //
+            // Get a full array of pixel values from a single frame.
+            // This disables navigation and overwrites any donwloaded firmware,
+            // so call to reset() is needed to restore them
+            //
+            // @param pixels The array where pixel values will be stored
+            //
+            void captureFrame(uint8_t pixels[NUMBER_OF_PIXELS_PER_FRAME]);
+
+            //
+            // Member function invoked when motion has ocurred and if a motion pin
+            // was specified when the object constructor was called.
+            // By default it invokes the function specified by a previous call to attach()
+            //
+            virtual void motionTrigger()
+                { motionTrigger_.call(); }
+
+            //
+            // Attach a function to call when a falling edge occurs on motion pin
+            //
+            // @param function A pointer to a function or 0 to set the attached function as none
+            //
+            void attach(void (*function)(void))
+                { motionTrigger_.attach(function); }
+
+            //
+            // Attach a member function to call when a falling edge occurs on motion pin
+            //
+            // @param object A reference to the object to call the member function on
+            // @param function A pointer to the member function to be called
+            //
+            template<typename T>
+            void attach(T& object, void (T::*member)(void))
+                { motionTrigger_.attach(object, member); }
+
+        private:
+            SPI spi_;
+            InterruptIn motion_;
+            DigitalOut ncs_;
+            
+            bool enabled_;            
+            int dx_, dy_;
+            int xCpi_, yCpi_;
+            
+            FunctionPointer motionTrigger_;
+    };
+}
+
+#endif /* ADNS9500_HPP_ */
\ No newline at end of file