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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
aplatanado
Date:
Thu Mar 22 17:36:49 2012 +0000
Parent:
2:ee0c13ef1320
Child:
4:dddfb08cebc2
Commit message:
fix capture frame.

Changed in this revision

adns9500.cpp Show annotated file Show diff for this revision Revisions of this file
adns9500.hpp Show annotated file Show diff for this revision Revisions of this file
examples/main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/adns9500.cpp	Thu Mar 22 15:04:33 2012 +0000
+++ b/adns9500.cpp	Thu Mar 22 17:36:49 2012 +0000
@@ -431,7 +431,7 @@
         yCpi_ = y_resolution * CPI_CHANGE_UNIT;
     }
     
-    void ADNS9500::captureFrame(uint8_t pixels[NUMBER_OF_PIXELS_PER_FRAME])
+    void ADNS9500::captureFrame(uint8_t* pixels)
     {
         if (! enabled_)
             error("ADNS9500::captureFrame : the sensor is not enabled\n");
@@ -445,24 +445,22 @@
         LONG_WAIT_US(2*DEFAULT_MAX_FRAME_PERIOD);
 
         // check for first pixel reading motion bit
-        while(true) {
+        int motion = spiReceive(MOTION);
+        WAIT_TSRR();
+        while(! ADNS9500_IF_FRAME_FIRST_PIXEL(motion)) {
             int motion = spiReceive(MOTION);
-            if (ADNS9500_IF_MOTION(motion))
-                break;
             WAIT_TSRR();
         }
-        WAIT_TSRR();
 
         // read pixel values
         spi_.write(PIXEL_BURST);
         WAIT_TSRAD();
-        for (uint8_t* p = pixels; p != pixels + sizeof(pixels); ++p) {
+        for (uint8_t* p = pixels; p != pixels + NUMBER_OF_PIXELS_PER_FRAME; ++p) {
+            *p = spi_.write(0x00);
             WAIT_TLOAD();
-            *p = spi_.write(PIXEL_BURST);
         }
 
-        // burst exit        
-        WAIT_TSCLKNCS();
+        // burst exit
         ncs_.write(1);
         WAIT_TBEXIT();
     }
--- a/adns9500.hpp	Thu Mar 22 15:04:33 2012 +0000
+++ b/adns9500.hpp	Thu Mar 22 17:36:49 2012 +0000
@@ -31,6 +31,7 @@
 #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_FRAME_FIRST_PIXEL(x)    (bool)(x & 0x01)
 #define ADNS9500_IF_OBSERVATION_TEST(x)     (bool)(x & ADNS9500_OBSERVATION_CHECK_BITS)
 #define ADNS9500_UINT16(ub, lb)             (((uint16_t)ub << 8) + (uint16_t)lb)
 #define ADNS9500_INT16(ub, lb)              ((((int16_t)(int8_t)ub) << 8) + (int16_t)lb)
@@ -84,7 +85,7 @@
         POWER_UP_RESET     = 0x3a,
         MOTION_BURST       = 0x50,
         SROM_LOAD_BURST    = 0x62,
-        PIXEL_BURST        = 0x62
+        PIXEL_BURST        = 0x64
     };
 
     //
@@ -259,9 +260,9 @@
             // 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
+            // @param pixels A pointer to the array where pixel values will be stored
             //
-            void captureFrame(uint8_t pixels[NUMBER_OF_PIXELS_PER_FRAME]);
+            void captureFrame(uint8_t* pixels);
 
             //
             // Member function invoked when motion has ocurred and if a motion pin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/main.cpp	Thu Mar 22 17:36:49 2012 +0000
@@ -0,0 +1,101 @@
+#include <mbed.h>
+#include <stdint.h>
+
+#include "adns9500.hpp"
+
+//#define USE_MOTION_BURST
+#define FRAME_CAPTURE
+
+const char* FIRMWARE_FILENAME = "/local/adns9500.fw";
+LocalFileSystem local("local");
+
+Ticker printData;
+adns9500::ADNS9500 sensor(p11, p12, p13, p15, adns9500::MAX_SPI_FREQUENCY, p14);
+
+bool motionTriggered = false;
+bool printDataTriggered = false;
+
+int motionCallbackCounter = 0;
+
+void printDataCallback()
+{
+    printDataTriggered = true;
+}
+
+void motionCallback()
+{
+    motionTriggered = true;
+    motionCallbackCounter++;
+}
+
+int main()
+{
+    int dataReadCounter = 0;
+    float totalMotionDx = 0.0;
+    float totalMotionDy = 0.0;
+
+#if defined (USE_MOTION_BURST)
+    adns9500::MotionData data;
+#elif defined (FRAME_CAPTURE)
+    uint8_t frame[adns9500::NUMBER_OF_PIXELS_PER_FRAME];
+#endif
+
+    sensor.reset();
+
+#if ! defined (FRAME_CAPTURE)
+    // Firmware upload
+    int crc = sensor.sromDownload(FIRMWARE_FILENAME);
+    printf("Firmware CRC: 0x%x (%s)\r\n", crc, FIRMWARE_FILENAME);
+#endif
+
+    // Enable laser
+    sensor.enableLaser();
+    printf("Laser enabled\r\n");
+
+#if ! defined (FRAME_CAPTURE)
+    printData.attach_us(&printDataCallback, 500);
+    sensor.attach(&motionCallback);
+#endif
+
+    while(true) {
+        if (motionTriggered) {
+            motionTriggered = false;
+            
+#if defined (USE_MOTION_BURST)
+            sensor.getMotionData(data);
+            totalMotionDx += data.dxMM;
+            totalMotionDy += data.dyMM;
+#else
+            float dx, dy;
+            sensor.getMotionDeltaMM(dx, dy);
+            totalMotionDx += dx;
+            totalMotionDy += dy;
+#endif
+            dataReadCounter++;
+        }
+
+        if (printDataTriggered) {
+            printDataTriggered = false;
+#if defined (USE_MOTION_BURST)
+            printf("Motion burst: %f, %f, quality=%d, average=%f, maximum=%d, minimum=%d, "
+                   "shutter=%d, periodo=%d, read=%d, irq=%d\r\n",
+                    totalMotionDx, totalMotionDy,
+                    data.surfaceQuality, data.averagePixel, data.maximumPixel, data.minimumPixel,
+                    data.shutter, data.framePeriod, dataReadCounter,
+                    motionCallbackCounter);
+#else
+            printf("Motion delta: %f, %f, read=%d, irq=%d\r\n",
+                totalMotionDx, totalMotionDy, dataReadCounter, motionCallbackCounter);
+#endif
+        }
+
+#if defined (FRAME_CAPTURE)
+        printf("FRAME:%d:", dataReadCounter);
+        sensor.captureFrame(frame);
+        for(uint8_t *p = frame; p != frame + sizeof(frame); ++p)
+            printf("%x", *p);
+        printf("\r\n");
+        dataReadCounter++;
+#endif
+    }
+}