ADNS2051 Optical Sensor library

ADNS2051.h

Committer:
clemente
Date:
2012-05-23
Revision:
0:462017ee2a5b

File content as of revision 0:462017ee2a5b:

/* mbed ADNS2051 Optical Sensor library.

    Copyright (c) 2011 NXP 3787
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
 
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
 
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
*/

#ifndef __ADNS2051_H
#define __ADNS2051_H

#include "mbed.h"


//
#define PRODUCTID_REG    0x00    // Product ID = 2 (Fixed value)
#define REVISIONID_REG    0x01    // Revision of IC [0xNN]
#define MOTION_REG        0x02    // Register 0x02 allows the user to determine if motion has occurred since the last time it was read
#define DELTAX_REG        0x03    // X movement is counts since last report. Absolute value is determined by resolution. Reading clears the register.
#define DELTAY_REG        0x04    // Y movement is counts since last report. Absolute value is determined by resolution. Reading clears the register.
#define SQUAL_REG        0x05    // Surface Quality. SQUAL is a measure of the number of features visible by the sensor in the
                                // current frame. The maximum value is 255. Since small changes in the current frame
                                // can result in changes in SQUAL, variations in SQUAL when looking at a surface are expected.
#define AVRPXL_REG        0x06    // Average Pixel value in current frame. Minimum value = 0, maximum = 63. The average pixel value can be adjusted every frame.
#define MAXPXL_REG        0x07    // Maximum Pixel value in current frame. Minimum value = 0, maximum value = 63. The maximum pixel value can be adjusted every frame.
#define CONFIGBIT_REG    0x0A    // Configuration bits. Register 0x0a allows the user to change the configuration of the sensor.
#define DTOUTLW_REG        0x0C    
#define DTOUTUP_REG        0x0D    // Once the pixel dump command is given, the sensor
                                // writes the address and the value for the first pixel into
                                // the Data_Out_Upper and Data_Out_Lower registers.
#define SHUTTERLW_REG    0x0E    
#define SHUTTERUP_REG    0x0F    // Shutter register.
#define FRMPRDLW_REG    0x10
#define FRMPRDUP_REG    0x11    // The frame period counter counts up until it overflows. Units are clock cycles.

// Motion register bits
#define MOTION_BIT        0x07    // Motion since last report: 0=no motion, 1=motion occurred, data ready on deltaX and Y regs.
#define LEDFAULT_BIT    0x05    // LED Fault detected: 0=no, 1=Fault detected
#define OVERFY_BIT        0x04    // Motion overflow Y, dY buffer has overflowed since last report: 0=no, 1=overflow
#define OVERFX_BIT        0x03    // Motion overflow X, dX buffer has overflowed since last report: 0=no, 1=overflow
#define RESOLUTION_BIT    0x00    // Resolution in counts x inch: 0=400, 1=800

// Confiuration register bits
#define RESET_BIT        0x07
#define LEDMODE_BIT        0x06
#define RESOLMODE_BIT    0x04
#define PIXDUMP_BIT        0x03
#define SLEEP_BIT        0x00

//
#define PIXDATAVALID_BIT    0x07

// Product ID value
#define PRODUCTID_VAL    0x02    // The value in this register does not change, it can be used to verify that the
                                // serial communications link is OK.

/** ADNS2051 Optical Sensor
* For this project I used an old Apple mouse. 
* Obviously modified for this project has made it unusable as a mouse for the PC.
*
* From the datasheet:
*   The ADNS-2051 is a low cost optical sensor used to
*   implement a non-mechanical tracking engine for
*   computer mice.
*   It is based on optical navigation technology, which
*   measures changes in position by optically acquiring
*   sequential surface images (frames) and mathematically
*   determining the direction and magnitude of
*   movement.
*   The sensor is housed in a 16-pin staggered dual inline
*   package (DIP).
*   
*   Features
*   . Precise optical navigation technology
*   . No mechanical moving parts
*   . Complete 2D motion sensor
*   . Serial interface and/or quadrature interface
*   . Smooth surface navigation
*   . Programmable frame speed up to 2300 frames per sec (fps)
*   . Accurate motion up to 14 ips
*   . 800 cpi resolution
*   . High reliability
*   . High speed motion detector
*   . No precision optical alignment
*   . On chip LED drive with regulated current
*   . Serial port registers
*   – Programming
*   – Data transfer
*
* Example code
*
* @code
* #include "ADNS2051.h"
*
* // pin configuration: p19: sout, p20: sclk
* ADNS2051 optical( p19, p20);
*
* // image buffer 
* unsigned char tmpmap[256];
*
* int main( void)
* {
*   printf( "Images from optical mouse: Init");
*   
*   // wait until the ADNS chip become ready...
*   while( optical.init() );
*   
*   optical.setframerate();
*   
*   printf("Images from optical mouse: PixelDump [Chip rev: 0x%X]", optical.get_revisionID());
*   wait( 1.0);
*   
*   optical.pixeldump( &tmpmap[0]);
*   // may be... do something with tmpmap...
*   while(1);
*   
* }
*/

class ADNS2051 {

public:
    /** ADNS2051 pin assignement.
     * 
     * @param sout  This pin is used as data in and data out.
     * @param sclk  This is the serial clock.
     */
    ADNS2051(  PinName sout, PinName sclk);
    
    /** Initialize the ADNS2051 chip.
     *
     * @param none
     * @return 0 for OK, 1 for bad.
     */
    unsigned char init( void);
    
    /** Read the motion register and update the deltaX and deltaY variable with the register value.
     *
     * @param none
     * @return a byte 0 = no motion, no led fault, no overflow
     *                1 =  motion
     *                2 =  led fault
     *                4 =  overflow
     */
    unsigned char readmotion( void);
    
    /** Get revision ID
     */
    unsigned char get_revisionID( void);
    
    /** Get product ID
     */
    unsigned char get_productID( void);
    
    /**  SQUAL is a measure of the number of features visible by the sensor in the
     * current frame. The maximum value is 255. Since small changes in the current frame
     * can result in changes in SQUAL, variations in SQUAL when looking at a surface are
     * expected. SQUAL is nearly equal to zero, if there is no surface below the sensor.
     *
     * @param the SQUAL value.
     */
    unsigned char surfacequality( void);
    
    /** Average Pixel value in current frame. Minimum value = 0,
     *  maximum = 63. The average pixel value can be adjusted every frame.
     *
     * @param none
     */
    unsigned char averagepixel( void);
    
    /** Maximum Pixel value in current frame. Minimum value = 0,
     *  maximum value = 63. The maximum pixel value can be adjusted every frame.
     *
     * @param none     
     */
    unsigned char maxpixelval( void);
    
    /** Change the default frame rate (1500 f/s) to 2300 f/s
     *
     * @param none     
     */    
    void setframerate( void);
    
    /** Verify the ADNS 2051 connection. 
     *
     * @param none
     * @return 0 OK, 1 Bad connection
     */
    unsigned char chkconn( void);
    
    /** Start the dump of the pixel map. Store the value to the array pixmap
     *
     * @param buffer array of 256 chars
     */
    void pixeldump( unsigned char *buffer);
    
    /** this values are updates every readmotion call.
     */
    signed char deltaX, deltaY;
    
    /** This value is the current resolution in count per inch. Can be 400 or 800 cpi
     */
    unsigned int currentresolution;
    
private:
    void sync( void);
    unsigned char read(unsigned char address);
    void write(unsigned char address, unsigned char value);
    //
    DigitalInOut _sout;
    DigitalOut _sclk;
    
};

#endif