Trackball based on the NXP LPC11U24 and the ADNS-9500

Dependencies:   ADNS9500 USBDevice mbed 25LCxxx_SPI

Files at this revision

API Documentation at this revision

Comitter:
xxann5
Date:
Mon Jan 14 04:27:55 2013 +0000
Parent:
6:4cb2c9a3abcd
Child:
8:5674f5ab61cd
Commit message:
Changed some define's to enum's. Also got a lot done towards having persistent settings/ADNS firmware saved on the eeprom.

Changed in this revision

25LCxxx_SPI.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
--- a/25LCxxx_SPI.lib	Sun Jan 06 19:48:26 2013 +0000
+++ b/25LCxxx_SPI.lib	Mon Jan 14 04:27:55 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/hlipka/code/25LCxxx_SPI/#3a3404dbd3eb
+http://mbed.org/users/hlipka/code/25LCxxx_SPI/#d9429070ea6f
--- a/main.cpp	Sun Jan 06 19:48:26 2013 +0000
+++ b/main.cpp	Mon Jan 14 04:27:55 2013 +0000
@@ -18,9 +18,12 @@
 
 #include "main.h"
 
+DigitalOut myled(p15);
+
 int main(void)
 {
 
+    printf( "Hi i just started running\n\r");
     uint8_t o;
     uint8_t i;
     MOUSE_TYPE mtype;
@@ -36,18 +39,28 @@
         i = 0;
     }
 
-
-    mouse = new USBMouse( mtype, 0x192f, 0x0000, 0x0001, o, i ) ;
+    // TODO switch to P#_#
+    SPI eeprom_spi( p11, p12, p13); // mosi, miso, sclk 
+    eeprom_spi.format(8,3);
+    eeprom_spi.frequency(1000000);
+    Ser25LCxxx eeprom( &eeprom_spi, p14, 0x10000, 0x20 );
+    
+    //Retreave settings from the EEPROM and override the default values.
+    for( int i = 0; i < sizeof(s)/sizeof(uint16_t); i++ ){
+        s[i] = get_setting( &eeprom, i );
+        printf( "Setting %02d: %d\r\n", i, s[i]);
+    }
 
-    if( mtype == RAW ){
-        program();
-    }
-    else{
-        track();
-    }
+
+    //if( mtype == RAW ){
+    //    program();
+    //}
+    //else{
+    //    track();
+    //}
 }
 
-void track(){
+void track( Ser25LCxxx *eeprom ){
     /* 
     * mosi miso sclk ncs FREQ, motion
     */
@@ -88,19 +101,37 @@
     
     sensor->reset();
     
-    uint16_t crc = sensor->sromDownload(adns9500FWArray, (uint16_t)ADNS9500_FIRMWARE_LEN );
+    //Retreave adns meta data from the EEPROM and override the default values.
+    for( int i = 0; i < sizeof(a)/sizeof(uint16_t); i++ ){
+        a[i] = get_adns_meta( eeprom, i );
+        printf( "ADNS Meta %02d: %d\r\n", i, s[i]);
+    }
+    
+    uint8_t *adns_fw;
+    adns_fw = get_adns_firmware( eeprom, 0, ADNS_FW_LEN );
+    
+    // We are now does with the eeprom 
+    delete eeprom;
+    
+    uint16_t crc = sensor->sromDownload( adns_fw, a[ADNS_FW_LEN] );
       
-    if( (uint16_t)ADNS6010_FIRMWARE_CRC != crc )
+    if( a[ADNS_CRC] != crc )
     {
-        error( "CRC does not match: [%x] [%x], Exiting.\r\n", (uint16_t)ADNS6010_FIRMWARE_CRC, crc );
+        error( "CRC does not match: [%x] [%x], Exiting.\r\n", a[ADNS_CRC], crc );
     }
+    
+    // The firmware was set correctly. Freeing the 3K! of ram.
+    delete adns_fw;
 
     sensor->enableLaser();
     
-    sensor->setResolution( default_motion_cpi );
+    sensor->setResolution( s[CPI_DEFAULT] );
     int btn_l_avg = 0;
+    DigitalOut myled(P0_7);
     while (true){
 
+
+        
         btn_l_avg=(btn_l_avg * 9 + btn_l * 10)/10;
         if (btn_l_avg > 5){
             btn_l_press();
@@ -111,7 +142,7 @@
 
         
         if( motion_triggered ){
-            led1 = !led1;
+
             motion_triggered = false;
 
             sensor->getMotionDelta(dx, dy);
@@ -131,18 +162,9 @@
 }
 
 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");
-            }
+
+    // We are now does with the eeprom 
+    //delete eeprom;
 }
 
 void motionCallback(){
@@ -151,20 +173,20 @@
 
 void btn_hr_press(){
     high_rez_active = true;
-    sensor->setResolution( default_hirez_cpi ); 
+    sensor->setResolution( s[CPI_HR_DEFAULT] ); 
 }
 void btn_hr_release(){
     high_rez_active = false;
-    sensor->setResolution( default_motion_cpi );
+    sensor->setResolution( s[CPI_DEFAULT] );
 }
 
 void btn_z_press(){
     z_axis_active = true;
-    sensor->setResolution( default_z_cpi );
+    sensor->setResolution( s[CPI_Z_DEFAULT] );
 }
 void btn_z_release(){
     z_axis_active = false;
-    sensor->setResolution( default_motion_cpi );
+    sensor->setResolution( s[CPI_DEFAULT] );
 }
 
 void btn_l_press(){
@@ -188,17 +210,79 @@
     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");
+
+/*
+ * The settings are kept in the first 'N' addresses of the of the EEPROM.
+ * They are 16bits long. The default settings are in a uint16_t array. So
+ * to set/get a setting you use the array value and multiple it by two.
+ * This way I can easily get all setting at the start of the program by
+ * simply looping through the array.
+ */
+
+
+void set_setting( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t val ){
+
+    int hl[2];
+    
+    // TODO: Its working but is it working the way i think its working
+    hl[0] = (int)val;
+    hl[1] = (int)(val >> 8);
+
+    eeprom->write( attrib * 2, 0x2, hl );
+
+}
+
+uint16_t get_setting( Ser25LCxxx *eeprom, uint16_t attrib ){
+    
+    uint16_t val;
+    int *hl;
+    
+    hl = eeprom->read( (attrib * 2), 0x2 );
+    val = UINT16( hl[1], hl[0] );
+    if( val != 0xFFFF ){
+        return val;
     }
+
+    return s[attrib];
 }
 
+void clear_setting( Ser25LCxxx *eeprom, uint16_t attrib ){
+    int val[2];
+    val[0] = val[1] = 0xFF;
+    eeprom->write( (attrib * 2) , 0x2, val );
+}
+
+/*
+ * Getting and setting the firmware is a bit easer as it is all 8bit.
+ */
+void set_adns_firmware( Ser25LCxxx *eeprom, uint16_t offset, uint16_t len, uint8_t* val ){
+    eeprom->write( (ADNS_FW_OFFSET + offset) , len, (int*)val );
+}
+
+uint8_t* get_adns_firmware( Ser25LCxxx *eeprom, uint16_t offset, uint16_t len ){
+    return (uint8_t*)eeprom->read( (ADNS_FW_OFFSET + offset), len );
+}
+
+/*
+ * Same deal as the trackball settings.
+ */
+ 
+void set_adns_meta( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t val ){
+
+    int hl[2];
+    
+    // TODO: Its working but is it working the way i think its working
+    hl[0] = (int)val;
+    hl[1] = (int)(val >> 8);
+    
+    eeprom->write( (ADNS_META_OFFSET + (attrib * 2 )), 0x2, hl );
+}
+
+uint16_t get_adns_meta( Ser25LCxxx *eeprom, uint16_t attrib ){
+    uint16_t val;
+    int *hl;
+    
+    hl = eeprom->read( (ADNS_META_OFFSET + (attrib * 2 )), 0x2 );
+    val = UINT16( hl[1], hl[0] );
+    return val;
+}
\ No newline at end of file
--- a/main.h	Sun Jan 06 19:48:26 2013 +0000
+++ b/main.h	Mon Jan 14 04:27:55 2013 +0000
@@ -38,45 +38,50 @@
 #include "adns9500.hpp"
 #include "Ser25lcxxx.h"
 
-#define CHAT_SET 0x01
-#define CHAT_GET 0x02
-    
-#define CHAT_MOTION_DEFAULT_CPI 0x01
-#define CHAT_MOTION_MAX_CPI     0x02
-#define CHAT_MOTION_MIN_CPI     0x03
-#define CHAT_MOTION_STEP_CPI    0x04
-#define CHAT_Z_DEFAULT_CPI      0x05
-#define CHAT_HR_DEFAULT_CPI     0x06
+enum cli_actions {
+    SET   = 0x01,
+    GET   = 0x02,
+    CLEAR = 0x03,
+    INIT  = 0x04,
+};
+
+enum settings {    
+    CPI_DEFAULT     = 0x00,
+    CPI_MAX         = 0x01,
+    CPI_MIN         = 0x02,
+    CPI_STEP        = 0x03,
+    CPI_Z_DEFAULT   = 0x04,
+    CPI_HR_DEFAULT  = 0x05,
     
-#define CHAT_VID                0x07
-#define CHAT_PID                0x08
-    
-#define CHAT_ADNS_SROM          0x09
+    VID             = 0x06,
+    PID             = 0x07,
+
+    LED_SHOW        = 0x08,
+    SETTINGS_OFFSET = 0x00
+};
 
-#define CHAT_LED_BEHAVIOR       0x0a
+enum ands_meta {
+    ADNS_CRC         = 0x0,
+    ADNS_ID          = 0x1,
+    ADNS_FW_LEN      = 0x2,
+    ADNS_FW_OFFSET   = 0xF000,
+    ADNS_META_OFFSET = 0xEFF0
+};
 
-#define CHAT_BTN_TICKER_FREQ    0x0b
-#define CHAT_BTN_ASSERT_COUNT   0x0c
-
-
+#define UINT16(ub, lb)             (uint16_t)(((ub & 0xff) << 8) | (lb & 0xff))
+#define INT16(ub, lb)              (int16_t)(((ub & 0xff) << 8) | (lb & 0xff))
   
 //This report will contain data to be sent
 HID_REPORT send_rep;
 HID_REPORT recv_rep;
 
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
+PinDetect btn_l(P1_25);
+PinDetect btn_m(P1_19);
+PinDetect btn_r(P0_20);
+PinDetect btn_z(P0_2);
+PinDetect btn_hr(P1_26);
 
-PinDetect btn_hr(p16);
-PinDetect btn_z(p17);
-DigitalIn btn_l(p18);
-PinDetect btn_m(p19);
-PinDetect btn_r(p20);
-
-
-DigitalIn btn_program(p22);
+DigitalIn btn_program(P0_4);
 
 adns9500::ADNS9500 *sensor;
 USBMouse *mouse;
@@ -85,9 +90,19 @@
 bool z_axis_active    = false;
 bool high_rez_active  = false;
 
-int default_motion_cpi = 1080;
-int default_z_cpi      = 90;
-int default_hirez_cpi  = 180;
+uint16_t s[9] = {
+    1080,    // CPI_DEFAULT
+    5040,    // CPI_MAX
+    0,       // CPI_MIN
+    90,      // CPI_STEP
+    90,      // CPI_Z_DEFAULT
+    180,     // CPI_HR_DEFULT
+    0x192f,  // VID
+    0x0000,  // PID
+    0,       // LED_SHOW
+};
+
+uint16_t a[3];
 
 void track();
 void program();
@@ -109,5 +124,12 @@
 void btn_r_press( void );
 void btn_r_release( void );
 
-void set( uint8_t attrib, uint8_t *val );
-void get( uint8_t attrib);
\ No newline at end of file
+void set_setting( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t val );
+uint16_t get_setting( Ser25LCxxx *eeprom, uint16_t attrib);
+void clear_setting( Ser25LCxxx *eeprom, uint16_t attrib);
+
+void set_adns_firmware( Ser25LCxxx *eeprom, uint16_t offset, uint16_t len, uint8_t* val );
+uint8_t* get_adns_firmware( Ser25LCxxx *eeprom, uint16_t offset, uint16_t len );
+
+void set_adns_meta( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t val );
+uint16_t get_adns_meta( Ser25LCxxx *eeprom, uint16_t attrib );
\ No newline at end of file