IPAB Neuromorphic / ADNS5020EN

ADNS5020EN.cpp

Committer:
IPAB
Date:
2010-07-10
Revision:
3:d1e20858380a
Parent:
2:ced74cb7e8ee

File content as of revision 3:d1e20858380a:

#include "ADNS5020EN.h"

ADNS5020EN::ADNS5020EN(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName cr, float freq)
        : _spi(mosi, miso, sclk), _cs(cs), _cr(cr) {

    // setup the spi connection to a given frequency (MHz)
    _spi.format(8,3);
    set_freq(freq);

    // Chip Reset
    creset();
    _cs = 1;
    wait_us(20);

    _false_readings = 0;
    _cpi = 500;

    int prod_id = cread(0x00); // read Product ID register
    int rev_id = cread(0x01); // read Revision ID register

    if ((prod_id!=18)||(rev_id!=1)) {

        error("The connection with the ADNS-5020-EN is not established\n");;

    }

}

// read the delta_X and delta_Y of the chip
void ADNS5020EN::read_deltas(int* a_dx, int* a_dy) {

    int * dx, * dy;
    dx=(int*)a_dx;
    dy=(int*)a_dy;
    *dx = 0;
    *dy = 0;

    int prod_id = cread(0x00); // read Product ID register
    int rev_id = cread(0x01); // read Revision ID register
    int motion = cread(0x02); // read Motion register

    if ((prod_id==18)&&(rev_id==1)&&(motion==128)) {

        *dx = MChipMotion(cread(0x03));
        *dy = MChipMotion(cread(0x04));

    } else if ((prod_id!=18)||(rev_id!=1)) {

        _false_readings ++;
        printf("====  FALSE Reading ====\r\n");

    }
}

void ADNS5020EN::read_deltas_mm(float* a_dx, float* a_dy) {

    float * dx, * dy;
    dx=(float*)a_dx;
    dy=(float*)a_dy;

    int i_dx, i_dy;

    read_deltas(&i_dx,&i_dy);

    *dx = counts_to_mm(i_dx);
    *dy = counts_to_mm(i_dy);

}

// Set new working frequency to the chip
void ADNS5020EN::set_freq(float freq) {

    _spi.frequency(freq*1000000);
}

// return the false readings value
int ADNS5020EN::falser() {

    return _false_readings;
}

// mouse chip - end process
void ADNS5020EN::end() {

    // Chip Reset
    creset();
    _cs = 1;
    wait_us(20);

    // Chip Power Down signal
    cwrite(0x8d,0x02);
    
}

// mouse chip - change resolurion
int ADNS5020EN::changeCPI(bool cpi=0) {

    if (cpi) {
        // Change cpi to 1000
        cwrite(0x8d,0x01);
        _cpi = 1000;
    } else {
        // Change cpi to 500
        cwrite(0x8d,0x00);
        _cpi = 500;
    }

    return cread(0x0d);
}

// mouse chip reset
void ADNS5020EN::creset() {

    _cr = 0;
    wait_us(2);
    _cr = 1;
    wait_ms(52);

}

// read a register
int ADNS5020EN::cread(int cregister) {

    // select the device by setting pin4 high
    _cs=0;

    // send the command to read the register
    _spi.write(cregister);
    wait_us(10);

    // send dummy byte
    int reply = _spi.write(0x00);

    // deselect the device by setting pin4 high
    _cs=1;
    wait_us(10);

    return reply;
}

// write data to a register
void ADNS5020EN::cwrite(int caddress, int cdata) {

    // select the device by setting pin4 high
    _cs=0;

    // send the command to read the register
    _spi.write(caddress);
    wait_us(10);

    // send dummy byte
    _spi.write(cdata);

    // deselect the device by setting pin4 high
    _cs=1;
    wait_us(40); // more than the minimum for safety
}


// Transform the reading of the mouse Delta register to actual motion
int ADNS5020EN::MChipMotion(int reading) {

    int displacement;
    if (reading <= 128) {
        displacement = reading;
    } else {
        displacement = reading - 256;
    }
    return displacement;

}

// Translate the readed counts from the chip into mm
float ADNS5020EN::counts_to_mm(int counts) {

    float INCHtoMM =  25.4;
    float result = (float) counts * INCHtoMM/_cpi;
    return result;

}