Trackball based on the NXP LPC11U24 and the ADNS-9500

Dependencies:   ADNS9500 USBDevice mbed 25LCxxx_SPI

main.cpp

Committer:
xxann5
Date:
2013-01-06
Revision:
6:4cb2c9a3abcd
Parent:
5:c7056267daa7
Child:
7:d6ee49a89009

File content as of revision 6:4cb2c9a3abcd:

/* Copyright (c) 2012-2013 Chris Majoros(chris@majoros.us), MIT License
*
* 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.
*/

#include "main.h"

int main(void)
{

    uint8_t o;
    uint8_t i;
    MOUSE_TYPE mtype;

    if( btn_program ){
        mtype = RAW;
        o = 64;
        i = 64;
    }
    else{
        mtype = REL_MOUSE;
        o = 0;
        i = 0;
    }


    mouse = new USBMouse( mtype, 0x192f, 0x0000, 0x0001, o, i ) ;

    if( mtype == RAW ){
        program();
    }
    else{
        track();
    }
}

void track(){
    /* 
    * mosi miso sclk ncs FREQ, motion
    */
    sensor = new adns9500::ADNS9500(p5, p6, p7, p8, adns9500::MAX_SPI_FREQUENCY, p21);
    
    send_rep.length = 8;
    
    btn_hr.mode(PullUp);
    btn_hr.attach_asserted(&btn_hr_press);
    btn_hr.attach_deasserted(&btn_hr_release);
    btn_hr.setSampleFrequency();

    btn_z.mode(PullUp);
    btn_z.attach_asserted(&btn_z_press);
    btn_z.attach_deasserted(&btn_z_release);
    btn_z.setSampleFrequency();
/*
    btn_l.mode(PullUp);
    btn_l.attach_asserted(&btn_l_press);
    btn_l.attach_deasserted(&btn_l_release);
    btn_l.setSampleFrequency();
*/
    btn_m.mode(PullUp);
    btn_m.attach_asserted(&btn_m_press);
    btn_m.attach_deasserted(&btn_m_release);
    btn_m.setSampleFrequency();

    btn_r.mode(PullUp);
    btn_r.attach_asserted(&btn_r_press);
    btn_r.attach_deasserted(&btn_r_release);
    btn_r.setSampleFrequency();
    //btn_r.setAssertValue( 0 );
    //btn_r.setSamplesTillAssert( 5 );
    
    int dx, dy;

    sensor->attach(&motionCallback);
    
    sensor->reset();
    
    uint16_t crc = sensor->sromDownload(adns9500FWArray, (uint16_t)ADNS9500_FIRMWARE_LEN );
      
    if( (uint16_t)ADNS6010_FIRMWARE_CRC != crc )
    {
        error( "CRC does not match: [%x] [%x], Exiting.\r\n", (uint16_t)ADNS6010_FIRMWARE_CRC, crc );
    }

    sensor->enableLaser();
    
    sensor->setResolution( default_motion_cpi );
    int btn_l_avg = 0;
    while (true){

        btn_l_avg=(btn_l_avg * 9 + btn_l * 10)/10;
        if (btn_l_avg > 5){
            btn_l_press();
        }
        else{
            btn_l_release();
        }

        
        if( motion_triggered ){
            led1 = !led1;
            motion_triggered = false;

            sensor->getMotionDelta(dx, dy);

            /*
             * The sensor does not know its upside down and backwords
             * so we are helping it out with the y axis.
             */
            if( z_axis_active ){
                mouse->scroll( - dy );
            }
            else{
                mouse->move( dx, - dy ); 
            }
        }
    }
}

void program(){
    led3 = !led3;
               switch (recv_rep.data[0]){
                    case CHAT_SET:
                        set(recv_rep.data[1],&recv_rep.data[2]);
                        break;
                    case CHAT_GET:
                        //get(recv_rep.data[1]);
                        break;
                default:
                    // FIXME: error handling.
                    printf("crap\r\n");
            }
}

void motionCallback(){
    motion_triggered = true;
}

void btn_hr_press(){
    high_rez_active = true;
    sensor->setResolution( default_hirez_cpi ); 
}
void btn_hr_release(){
    high_rez_active = false;
    sensor->setResolution( default_motion_cpi );
}

void btn_z_press(){
    z_axis_active = true;
    sensor->setResolution( default_z_cpi );
}
void btn_z_release(){
    z_axis_active = false;
    sensor->setResolution( default_motion_cpi );
}

void btn_l_press(){
    mouse->press(MOUSE_LEFT);
}
void btn_l_release(){
    mouse->release(MOUSE_LEFT);
}

void btn_m_press(){
    mouse->press(MOUSE_MIDDLE);
}
void btn_m_release(){
    mouse->release(MOUSE_MIDDLE);
}

void btn_r_press(){
    mouse->press(MOUSE_RIGHT);
}
void btn_r_release(){
    mouse->release(MOUSE_RIGHT);
}

void set( uint8_t attrib, uint8_t *val ){
    switch (attrib){
        case CHAT_MOTION_DEFAULT_CPI:
            default_motion_cpi = *val;
            break;
        case CHAT_Z_DEFAULT_CPI:
            default_z_cpi = *val;
            break;
        default:
            // FIXME: error handling.
            printf("crap\r\n");
    }
}