Trackball based on the NXP LPC11U24 and the ADNS-9500
Dependencies: ADNS9500 USBDevice mbed 25LCxxx_SPI
main.cpp
00001 /* 00002 * loststone is free sofware: you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License 3 as published by 00004 * the Free Software Foundation. 00005 * 00006 * loststone is distributed in the hope that it will be useful, 00007 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00008 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00009 * GNU General Public License for more details. 00010 * 00011 * You should have received a copy of the GNU General Public License 00012 * along with loststone. If not, see <http://www.gnu.org/licenses/gpl.txt>. 00013 * 00014 * Copyright (c) 2012-2013 Chris Majoros(chris@majoros.us), GNU3 00015 */ 00016 00017 #include "main.h" 00018 00019 00020 int main(void) 00021 { 00022 00023 printf("And away we go.\n\r"); 00024 activity = 1; 00025 run_mode.mode(PullUp); 00026 Ser25LCxxx *eeprom; 00027 00028 #ifdef MBED 00029 SPI eeprom_spi( p11, p12, p13); // mosi, miso, sclk 00030 #elif 00031 SPI eeprom_spi( P0_21, P0_22, P1_20); // mosi, miso, sclk 00032 #endif 00033 00034 eeprom_spi.format(8,3); 00035 eeprom_spi.frequency(1000000); 00036 00037 #ifdef MBED 00038 eeprom = new Ser25LCxxx( &eeprom_spi, p15, 0x10000, 0x20 ); 00039 #elif 00040 eeprom = new Ser25LCxxx( &eeprom_spi, P1_27, 0x10000, 0x20 ); 00041 #endif 00042 00043 //retreave default and system settings from the EEPROM and override the default values. 00044 printf("Loading settings\n\r"); 00045 for( int i = 0; i < sizeof(s)/sizeof(uint16_t); i++ ){ 00046 printf("Setting %d: %X\r\n", i, s[i]); 00047 //set_setting( eeprom, i, s[i], SETTINGS_BASE ); 00048 //s[i] = get_setting( eeprom, i, SETTINGS_BASE ); 00049 printf("Setting %d: %X\r\n", i, s[i]); 00050 } 00051 00052 //eeprom->write( s[ADNS_FW_OFFSET], ADNS9500_FIRMWARE_LEN, adns9500FWArray ); 00053 00054 if( run_mode ){ 00055 printf("Tracking mode\n\r"); 00056 track( eeprom ); 00057 } 00058 else{ 00059 printf("Programming mode\n\r"); 00060 program( eeprom ); 00061 } 00062 } 00063 00064 void track( Ser25LCxxx *eeprom ){ 00065 activity = 0; 00066 /* 00067 * mosi miso sclk ncs FREQ, motion 00068 */ 00069 mouse = new USBMouse( REL_MOUSE, s[VID], s[PID], s[RELEASE]) ; 00070 00071 /* 00072 * mosi == p5 / P0_9 00073 * miso == p6 / P0_8 00074 * sclk == p7 / P0_10 00075 * ncs == p8 / P1_16 00076 * spi_frequency = MAX_SPI_FREQUENCY 00077 * motion == p14 / P0_22 00078 */ 00079 00080 printf("Creating sensor object\n\r"); 00081 #ifdef MBED 00082 adns9500::ADNS9500 sensor(p5, p6, p7, p8, adns9500::MAX_SPI_FREQUENCY); 00083 #elif 00084 adns9500::ADNS9500 sensor(P0_9, P0_8, P0_10, P1_16, adns9500::MAX_SPI_FREQUENCY); 00085 #endif 00086 00087 static fn press_funcs[] = { 00088 btn_l_press, 00089 btn_m_press, 00090 btn_r_press, 00091 btn_f_press, 00092 btn_b_press, 00093 btn_z_press, 00094 btn_hr_press}; 00095 00096 static fn release_funcs[] = { 00097 btn_l_release, 00098 btn_m_release, 00099 btn_r_release, 00100 btn_f_release, 00101 btn_b_release, 00102 btn_z_release, 00103 btn_hr_release}; 00104 00105 printf("Inisializing buttons\n\r"); 00106 00107 // Mouse buttons 00108 btn_a.mode(PullNone); 00109 btn_a.fall(press_funcs[s[BTN_A]]); 00110 btn_a.rise(release_funcs[s[BTN_A]]); 00111 00112 btn_b.mode(PullNone); 00113 btn_b.fall(press_funcs[s[BTN_B]]); 00114 btn_b.rise(release_funcs[s[BTN_B]]); 00115 00116 btn_c.mode(PullNone); 00117 btn_c.fall(press_funcs[s[BTN_C]]); 00118 btn_c.rise(release_funcs[s[BTN_C]]); 00119 00120 btn_d.mode(PullNone); 00121 btn_d.fall(press_funcs[s[BTN_D]]); 00122 btn_d.rise(release_funcs[s[BTN_D]]); 00123 00124 btn_e.mode(PullNone); 00125 btn_e.fall(press_funcs[s[BTN_E]]); 00126 btn_e.rise(release_funcs[s[BTN_E]]); 00127 00128 btn_f.mode(PullNone); 00129 btn_f.fall(press_funcs[s[BTN_F]]); 00130 btn_f.rise(release_funcs[s[BTN_F]]); 00131 00132 btn_g.mode(PullNone); 00133 btn_g.fall(press_funcs[s[BTN_G]]); 00134 btn_g.rise(release_funcs[s[BTN_G]]); 00135 00136 // Profile buttons 00137 prfl_a.mode(PullUp); 00138 prfl_a.fall(&prfl_a_set); 00139 prfl_a.rise(&prfl_stub); 00140 00141 prfl_b.mode(PullUp); 00142 prfl_b.fall(&prfl_b_set); 00143 prfl_b.rise(&prfl_stub); 00144 00145 prfl_c.mode(PullUp); 00146 prfl_c.fall(&prfl_c_set); 00147 prfl_c.rise(&prfl_stub); 00148 00149 prfl_d.mode(PullUp); 00150 prfl_d.fall(&prfl_d_set); 00151 prfl_d.rise(&prfl_stub); 00152 00153 prfl_e.mode(PullUp); 00154 prfl_e.fall(&prfl_e_set); 00155 prfl_e.rise(&prfl_stub); 00156 00157 debug.mode(PullUp); 00158 debug.fall(&debug_out); 00159 debug.rise(&debug_out); 00160 00161 int16_t dx, dy; 00162 float mx, my; 00163 00164 sensor.reset(); 00165 00166 uint8_t *adns_fw; 00167 00168 //eeprom->write(ADNS_FW_OFFSET, ADNS_FW_LEN, adns9500FWArray); 00169 //adns_fw = eeprom->read( ADNS_FW_OFFSET, ADNS_FW_LEN ); 00170 //eeprom->write( s[ADNS_FW_OFFSET], ADNS9500_FIRMWARE_LEN, adns9500FWArray ); 00171 00172 activity = 1; 00173 printf("Loading sensor firmware\r\n"); 00174 uint16_t crc = sensor.sromDownload( adns9500FWArray, ADNS9500_FIRMWARE_LEN ); //FIXME 00175 00176 if( ADNS6010_FIRMWARE_CRC != crc ){ //ADNS6010_FIRMWARE_CRC 00177 printf("Firmware CRC does not match [%X] [%X]\n\r", 00178 ADNS6010_FIRMWARE_CRC, 00179 crc); 00180 while (true){ 00181 activity = 0; 00182 wait(0.2); 00183 activity = 1; 00184 wait(0.2); 00185 } 00186 } 00187 else{ 00188 activity = 0; 00189 printf("Firmware CRC matches [%X] [%X]\n\r", 00190 ADNS6010_FIRMWARE_CRC, 00191 crc); 00192 } 00193 00194 // The firmware was set correctly. Freeing the 3K! of ram. 00195 //delete adns_fw; 00196 00197 printf("Enableing lazer\n\r"); 00198 sensor.enableLaser(); 00199 sensor.setResolution( s[CPI_X], s[CPI_Y] ); 00200 00201 printf("Starting Loop\n\r"); 00202 activity = 1; 00203 //rest_counter = 0; 00204 while (true){ 00205 //rest_counter++; 00206 /* 00207 * Moved the setResolution calls out of the interupt callbacks as they 00208 * havequite a few waits in them. I am hopping this is the reasion why 00209 * the hr and z buttons on occation stick or don't work the first time 00210 * you press them. 00211 */ 00212 if( set_res_hr ){ 00213 printf("Setting High hez\n\r"); 00214 set_res_hr = false; 00215 sensor.setResolution( s[CPI_HR_X], s[CPI_HR_Y] ); 00216 } 00217 00218 if( set_res_z ){ 00219 printf("Setting Z rez\n\r"); 00220 set_res_z = false; 00221 sensor.setResolution( s[CPI_Z], s[CPI_H] ); 00222 } 00223 00224 if( set_res_default ){ 00225 printf("Setting default rez\n\r"); 00226 set_res_default = false; 00227 sensor.setResolution( s[CPI_X], s[CPI_Y] ); 00228 } 00229 00230 if( !motion_in){ 00231 00232 motion_triggered = false; 00233 00234 sensor.getMotionDelta(dx, dy); 00235 if( dx == 0 and dy == 0 ){ 00236 // FIXME: why is the ADNS9500 dropping the motion pin and then 00237 // giving me no motion? Do I have somthing wired up wrong? 00238 continue; 00239 } 00240 /* 00241 * The sensor is not aware of its orientation so we need to muck 00242 * with the values a it. 00243 */ 00244 if( z_axis_active ){ 00245 printf("scroll,%X,%X,\n\r", -dx, dy); 00246 mouse->scroll( dy, - dx ); 00247 } 00248 else{ 00249 00250 mx = (float(abs(dx))/float(s[CPI_X_MULITIPLYER]) + 1.0); 00251 my = (float(abs(dy))/float(s[CPI_Y_MULITIPLYER]) + 1.0); 00252 00253 printf("motion,%X,%X %.4f,%.4f %X,%X\n\r", -dx, dy, mx, my, int(- (dx * mx)), int(dy * my) ); 00254 00255 mouse->move( - (dx * mx), (dy * my) ); 00256 //printf("rest_coutner,%d\n\r", rest_counter); 00257 //rest_counter = 0; 00258 } 00259 } 00260 00261 00262 // Load the current profile. 00263 // This rights the first 10 16bit values of the s array from the selected profile. 00264 // 00265 // Base is calculated... 00266 // selected profile * profile length * 2 + profile base 00267 // 00268 // (3 * 7 * 2) + 64 (multiplying by two because they are 16bit values. 00269 // TODO: should i move this to a function? 00270 if( profile_load ){ 00271 // for( int i = 0; i < PROFILE_LEN; i++ ){ 00272 // //s[i] = get_setting( eeprom, i, (s[PROFILE_CURRENT] * PROFILE_LEN) + PROFILE_BASE ); 00273 // } 00274 // sensor.setResolution( s[CPI_X], s[CPI_Y] ); 00275 profile_load = false; 00276 } 00277 } 00278 } 00279 00280 void program( Ser25LCxxx *eeprom ){ 00281 00282 00283 //USBHID *hid = new USBHID( 64, 64, 0x192f, 0x0, 0x0); 00284 USBHID *hid = new USBHID(); 00285 //This report will contain data to be sent 00286 HID_REPORT send_rep; 00287 HID_REPORT recv_rep; 00288 00289 send_rep.length = 64; 00290 uint16_t base; 00291 uint16_t len; 00292 //Fill the report 00293 for (int i = 0; i < send_rep.length; i++) { 00294 send_rep.data[i] = rand() & 0xff; 00295 } 00296 00297 //Send the report 00298 //hid->send(&send_rep); 00299 00300 uint8_t *tmp; 00301 00302 printf("Entering loop\n\r"); 00303 while (1) { 00304 if( hid->readNB(&recv_rep)) { 00305 printf("Receaved some data.\n\r"); 00306 switch ((recv_rep.data[0])){ 00307 case SET: 00308 //set_setting( eeprom, recv_rep.data[1], UINT16(recv_rep.data[2],recv_rep.data[3])); 00309 break; 00310 case GET: 00311 //tmp = get_setting( eeprom, recv_rep.data[1] ); 00312 00313 //send_rep.data[0] = (int)tmp; 00314 //send_rep.data[1] = (int)(tmp >> 8); 00315 00316 //hid->send(&send_rep); 00317 00318 break; 00319 case CLEAR: 00320 //clear_setting( eeprom, recv_rep.data[1] ); 00321 break; 00322 case INIT: 00323 eeprom->clearMem(); 00324 break; 00325 case LOAD_DATA: 00326 printf("LOADING DATA\n\r"); 00327 base = UINT16( recv_rep.data[1], recv_rep.data[2] ); 00328 len = recv_rep.data[3]; 00329 printf("BASE: %X LEN: %X\n\r", base, len); 00330 load_data( eeprom, base, len, &recv_rep.data[4] ); 00331 wait(0.1); 00332 tmp = get_data( eeprom, base, len ); 00333 printf("BASE: %X LEN: %X\n\r", base, len); 00334 for( uint16_t i=0; i < (len); i++){ 00335 printf("%X\n\r", tmp[i]); 00336 send_rep.data[i] = tmp[i]; //FIXME 00337 } 00338 hid->send(&send_rep); 00339 delete( tmp); 00340 break; 00341 case GET_DATA: 00342 //base = UINT16( recv_rep.data[1], recv_rep.data[2] ); 00343 //len = UINT16( recv_rep.data[3], recv_rep.data[4] ); 00344 //tmp = get_data( Ser25LCxxx *eeprom, uint16_t base, uint16_t len ){ 00345 default: 00346 // FIXME: error handling. 00347 break; 00348 } 00349 } 00350 } 00351 } 00352 00353 void btn_l_press(){ 00354 printf("button,left,press\n\r"); 00355 mouse->press(MOUSE_LEFT); 00356 } 00357 void btn_l_release(){ 00358 printf("button,left,release\n\r"); 00359 mouse->release(MOUSE_LEFT); 00360 } 00361 00362 void btn_m_press(){ 00363 //mouse->press(MOUSE_MIDDLE); 00364 } 00365 void btn_m_release(){ 00366 //mouse->release(MOUSE_MIDDLE); 00367 } 00368 00369 void btn_r_press(){ 00370 printf("button,right,press\n\r"); 00371 mouse->press(MOUSE_RIGHT); 00372 } 00373 00374 void btn_r_release(){ 00375 printf("button,right,release\n\r"); 00376 mouse->release(MOUSE_RIGHT); 00377 } 00378 00379 void btn_f_press(){ 00380 printf("button,forword,press\n\r"); 00381 mouse->press(MOUSE_FORWORD); 00382 } 00383 void btn_f_release(){ 00384 printf("button,forword,release\n\r"); 00385 mouse->release(MOUSE_FORWORD); 00386 } 00387 00388 void btn_b_press(){ 00389 printf("button,back,press\n\r"); 00390 mouse->press(MOUSE_BACK); 00391 } 00392 00393 void btn_b_release(){ 00394 printf("button,back,release\n\r"); 00395 mouse->release(MOUSE_BACK); 00396 } 00397 00398 void btn_hr_press(){ 00399 printf("button,high_res,press\n\r"); 00400 set_res_hr = true; 00401 set_res_default = false; 00402 high_rez_active = true; 00403 } 00404 void btn_hr_release(){ 00405 printf("button,high_res,release\n\r"); 00406 set_res_hr = false; 00407 set_res_default = true; 00408 high_rez_active = false; 00409 } 00410 00411 void btn_z_press(){ 00412 printf("button,z,press\n\r"); 00413 set_res_z = true; 00414 set_res_default = false; 00415 z_axis_active = true; 00416 } 00417 void btn_z_release(){ 00418 printf("button,z,release\n\r"); 00419 set_res_z = false; 00420 set_res_default = true; 00421 z_axis_active = false; 00422 } 00423 00424 void prfl_a_set(){ 00425 s[PROFILE_CURRENT] = 0; 00426 profile_load = true; 00427 } 00428 00429 void prfl_b_set(){ 00430 s[PROFILE_CURRENT] = 1; 00431 profile_load = true; 00432 } 00433 00434 void prfl_c_set(){ 00435 s[PROFILE_CURRENT] = 2; 00436 profile_load = true; 00437 } 00438 00439 void prfl_d_set(){ 00440 s[PROFILE_CURRENT] = 3; 00441 profile_load = true; 00442 } 00443 00444 void prfl_e_set(){ 00445 s[PROFILE_CURRENT] = 4; 00446 profile_load = true; 00447 } 00448 00449 void prfl_stub(){ 00450 } 00451 00452 void debug_out(){ 00453 printf("motion_triggerd %d\n\r" , motion_triggered); 00454 printf("z_axis_active %d\n\r", z_axis_active); 00455 printf("high_rez_active %d\n\r", high_rez_active); 00456 printf("profile_load %d\n\r", profile_load); // Always inishally load the profile even if it might be the same. 00457 printf("set_res_hr %d\n\r", set_res_hr); 00458 printf("set_res_z %d\n\r" , set_res_z); 00459 printf("set_res_default %d\n\r", set_res_default); 00460 } 00461 00462 /* 00463 * The settings are kept in the first 'N' addresses of the of the EEPROM. 00464 * They are 16bits long. The default settings are in a uint16_t array. So 00465 * to set/get a setting you use the array value and multiple it by two. 00466 * This way I can easily get all setting at the start of the program by 00467 * simply looping through the array. 00468 */ 00469 00470 00471 int set_setting( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t val, uint16_t base_address ){ 00472 00473 uint8_t hl[2]; 00474 00475 // TODO: Its working but is it working the way i think its working 00476 hl[0] = (int)val; 00477 hl[1] = (int)(val >> 8); 00478 00479 printf("Set Setting %d: L[%X] H[%X]\n\r", attrib, hl[0], hl[1] ); 00480 00481 if ( eeprom->write( attrib * 2, 0x2, hl )){ 00482 return true; 00483 } 00484 return false; 00485 } 00486 00487 uint16_t get_setting( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t base_address ){ 00488 00489 uint16_t val; 00490 uint8_t *hl; 00491 00492 hl = eeprom->read( (attrib * 2) + base_address, 0x2 ); 00493 printf("Get Setting %d: L[%X] H[%X]\n\r", attrib, hl[0], hl[1] ); 00494 val = UINT16( hl[1], hl[0] ); 00495 if( val != 0xFFFF ){ 00496 return val; 00497 } 00498 00499 return s[attrib]; 00500 } 00501 00502 void clear_setting( Ser25LCxxx *eeprom, uint16_t attrib, uint16_t base_address ){ 00503 uint8_t val[2]; 00504 val[0] = val[1] = 0xFF; 00505 eeprom->write( (attrib * 2) + base_address , 0x2, val ); 00506 } 00507 00508 00509 /* 00510 * Getting and setting the firmware is a bit easer as it is all 8bit. 00511 */ 00512 void load_data( Ser25LCxxx *eeprom, uint16_t base, uint16_t len, const uint8_t* data ){ 00513 eeprom->write( base , len, data ); 00514 } 00515 00516 uint8_t* get_data( Ser25LCxxx *eeprom, uint16_t base, uint16_t len ){ 00517 return (uint8_t*)eeprom->read( base, len ); 00518 }
Generated on Thu Jul 14 2022 10:56:43 by 1.7.2