APDS-9960手势检测、接近检测、数字环境光感(ALS)和色感(RGBC)传感器驱动(基于传感器管理组件)
1 /** 2 * @file APDS_9960.c 3 * @brief APDS-9960传感器的源文件 4 * @version 0.1 5 * @date 2019-07-02 6 * 7 * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. 8 * 9 */ 10 /*----------------------------------------------------------------------------- 11 header 12 -----------------------------------------------------------------------------*/ 13 #include "string.h" 14 #include "APDS_9960.h" 15 #include "ci110x_i2c.h" 16 #include "ci110x_gpio.h" 17 #include "ci110x_scu.h" 18 #include "ci_misc.h" 19 #include "ci_log.h" 20 21 /*----------------------------------------------------------------------------- 22 define 23 -----------------------------------------------------------------------------*/ 24 #define DEBUG 0 25 26 /* APDS-9960 I2C address */ 27 #define APDS9960_I2C_ADDR 0x39/*!< APDS-9960传感器IIC总线地址 */ 28 29 /* Gesture parameters */ 30 #define GESTURE_THRESHOLD_OUT 10 31 #define GESTURE_SENSITIVITY_1 50 32 #define GESTURE_SENSITIVITY_2 20 33 34 /* Error code for returned values */ 35 #define ERROR 0xFF 36 37 /* Acceptable device IDs */ 38 #define APDS9960_ID_1 0xAB 39 #define APDS9960_ID_2 0x9C 40 41 /* Misc parameters */ 42 #define FIFO_PAUSE_TIME 30 /*!< Wait period (ms) between FIFO reads */ 43 44 /* APDS-9960 register addresses */ 45 #define APDS9960_ENABLE 0x80 46 #define APDS9960_ATIME 0x81 47 #define APDS9960_WTIME 0x83 48 #define APDS9960_AILTL 0x84 49 #define APDS9960_AILTH 0x85 50 #define APDS9960_AIHTL 0x86 51 #define APDS9960_AIHTH 0x87 52 #define APDS9960_PILT 0x89 53 #define APDS9960_PIHT 0x8B 54 #define APDS9960_PERS 0x8C 55 #define APDS9960_CONFIG1 0x8D 56 #define APDS9960_PPULSE 0x8E 57 #define APDS9960_CONTROL 0x8F 58 #define APDS9960_CONFIG2 0x90 59 #define APDS9960_ID 0x92 60 #define APDS9960_STATUS 0x93 61 #define APDS9960_CDATAL 0x94 62 #define APDS9960_CDATAH 0x95 63 #define APDS9960_RDATAL 0x96 64 #define APDS9960_RDATAH 0x97 65 #define APDS9960_GDATAL 0x98 66 #define APDS9960_GDATAH 0x99 67 #define APDS9960_BDATAL 0x9A 68 #define APDS9960_BDATAH 0x9B 69 #define APDS9960_PDATA 0x9C 70 #define APDS9960_POFFSET_UR 0x9D 71 #define APDS9960_POFFSET_DL 0x9E 72 #define APDS9960_CONFIG3 0x9F 73 #define APDS9960_GPENTH 0xA0 74 #define APDS9960_GEXTH 0xA1 75 #define APDS9960_GCONF1 0xA2 76 #define APDS9960_GCONF2 0xA3 77 #define APDS9960_GOFFSET_U 0xA4 78 #define APDS9960_GOFFSET_D 0xA5 79 #define APDS9960_GOFFSET_L 0xA7 80 #define APDS9960_GOFFSET_R 0xA9 81 #define APDS9960_GPULSE 0xA6 82 #define APDS9960_GCONF3 0xAA 83 #define APDS9960_GCONF4 0xAB 84 #define APDS9960_GFLVL 0xAE 85 #define APDS9960_GSTATUS 0xAF 86 #define APDS9960_IFORCE 0xE4 87 #define APDS9960_PICLEAR 0xE5 88 #define APDS9960_CICLEAR 0xE6 89 #define APDS9960_AICLEAR 0xE7 90 #define APDS9960_GFIFO_U 0xFC 91 #define APDS9960_GFIFO_D 0xFD 92 #define APDS9960_GFIFO_L 0xFE 93 #define APDS9960_GFIFO_R 0xFF 94 95 /* Bit fields */ 96 #define APDS9960_PON 0x01 97 #define APDS9960_AEN 0x02 98 #define APDS9960_PEN 0x04 99 #define APDS9960_WEN 0x08 100 #define APSD9960_AIEN 0x10 101 #define APDS9960_PIEN 0x20 102 #define APDS9960_GEN 0x40 103 #define APDS9960_GVALID 0x01 104 105 /* On/Off definitions */ 106 #define OFF 0 107 #define ON 1 108 109 /* Acceptable parameters for set_mode */ 110 #define POWER 0 111 #define AMBIENT_LIGHT 1 112 #define PROXIMITY 2 113 #define WAIT 3 114 #define AMBIENT_LIGHT_INT 4 115 #define PROXIMITY_INT 5 116 #define GESTURE 6 117 #define ALL 7 118 119 /* LED Drive values */ 120 #define LED_DRIVE_100MA 0 121 #define LED_DRIVE_50MA 1 122 #define LED_DRIVE_25MA 2 123 #define LED_DRIVE_12_5MA 3 124 125 /* Proximity Gain (PGAIN) values */ 126 #define PGAIN_1X 0 127 #define PGAIN_2X 1 128 #define PGAIN_4X 2 129 #define PGAIN_8X 3 130 131 /* ALS Gain (AGAIN) values */ 132 #define AGAIN_1X 0 133 #define AGAIN_4X 1 134 #define AGAIN_16X 2 135 #define AGAIN_64X 3 136 137 /* Gesture Gain (GGAIN) values */ 138 #define GGAIN_1X 0 139 #define GGAIN_2X 1 140 #define GGAIN_4X 2 141 #define GGAIN_8X 3 142 143 /* LED Boost values */ 144 #define LED_BOOST_100 0 145 #define LED_BOOST_150 1 146 #define LED_BOOST_200 2 147 #define LED_BOOST_300 3 148 149 /* Gesture wait time values */ 150 #define GWTIME_0MS 0 151 #define GWTIME_2_8MS 1 152 #define GWTIME_5_6MS 2 153 #define GWTIME_8_4MS 3 154 #define GWTIME_14_0MS 4 155 #define GWTIME_22_4MS 5 156 #define GWTIME_30_8MS 6 157 #define GWTIME_39_2MS 7 158 159 /* Default values */ 160 #define DEFAULT_ATIME 219 // 103ms 161 #define DEFAULT_WTIME 246 // 27ms 162 #define DEFAULT_PROX_PPULSE 0x87 // 16us, 8 pulses 163 #define DEFAULT_GESTURE_PPULSE 0x89 // 16us, 10 pulses 164 #define DEFAULT_POFFSET_UR 0 // 0 offset 165 #define DEFAULT_POFFSET_DL 0 // 0 offset 166 #define DEFAULT_CONFIG1 0x60 // No 12x wait (WTIME) factor 167 #define DEFAULT_LDRIVE LED_DRIVE_100MA 168 #define DEFAULT_PGAIN PGAIN_4X 169 #define DEFAULT_AGAIN AGAIN_4X 170 #define DEFAULT_PILT 0 // Low proximity threshold 171 #define DEFAULT_PIHT 50 // High proximity threshold 172 #define DEFAULT_AILT 0xFFFF // Force interrupt for calibration 173 #define DEFAULT_AIHT 0 174 #define DEFAULT_PERS 0x11 // 2 consecutive prox or ALS for int. 175 #define DEFAULT_CONFIG2 0x01 // No saturation interrupts or LED boost 176 #define DEFAULT_CONFIG3 0 // Enable all photodiodes, no SAI 177 #define DEFAULT_GPENTH 40 // Threshold for entering gesture mode 178 #define DEFAULT_GEXTH 30 // Threshold for exiting gesture mode 179 #define DEFAULT_GCONF1 0x40 // 4 gesture events for int., 1 for exit 180 #define DEFAULT_GGAIN GGAIN_4X 181 #define DEFAULT_GLDRIVE LED_DRIVE_100MA 182 #define DEFAULT_GWTIME GWTIME_2_8MS 183 #define DEFAULT_GOFFSET 0 // No offset scaling for gesture mode 184 #define DEFAULT_GPULSE 0xC9 // 32us, 10 pulses 185 #define DEFAULT_GCONF3 0 // All photodiodes active during gesture 186 #define DEFAULT_GIEN 0 // Disable gesture interrupts 187 188 /*----------------------------------------------------------------------------- 189 extern 190 -----------------------------------------------------------------------------*/ 191 192 /*----------------------------------------------------------------------------- 193 struct / enum / union 194 -----------------------------------------------------------------------------*/ 195 /* Direction definitions */ 196 enum 197 { 198 DIR_NONE, 199 DIR_LEFT, 200 DIR_RIGHT, 201 DIR_UP, 202 DIR_DOWN, 203 DIR_NEAR, 204 DIR_FAR, 205 DIR_ALL 206 }; 207 208 /* State definitions */ 209 enum 210 { 211 NA_STATE, 212 NEAR_STATE, 213 FAR_STATE, 214 ALL_STATE 215 }; 216 /* Container for gesture data */ 217 typedef struct 218 { 219 uint8_t u_data[32]; 220 uint8_t d_data[32]; 221 uint8_t l_data[32]; 222 uint8_t r_data[32]; 223 uint8_t index; 224 uint8_t total_gestures; 225 uint8_t in_threshold; 226 uint8_t out_threshold; 227 }gesture_data_type; 228 229 /*----------------------------------------------------------------------------- 230 global 231 -----------------------------------------------------------------------------*/ 232 /* Members */ 233 gesture_data_type gesture_data_; 234 235 int gesture_ud_delta_; 236 int gesture_lr_delta_; 237 int gesture_ud_count_; 238 int gesture_lr_count_; 239 int gesture_near_count_; 240 int gesture_far_count_; 241 int gesture_state_; 242 int gesture_motion_; 243 244 void (*apds_callback)(void); 245 246 /*----------------------------------------------------------------------------- 247 declare 248 -----------------------------------------------------------------------------*/ 249 250 /*----------------------------------------------------------------------------- 251 function 252 -----------------------------------------------------------------------------*/ 253 static void delay_ms(int ms) 254 { 255 int i=0; 256 while(ms--) 257 { 258 for(i=0;i<0x1A80;i++); 259 } 260 } 261 262 /** 263 * @brief Constructor - Instantiates sparkfun_apds9960 object 264 */ 265 void sparkfun_apds9960(void) 266 { 267 gesture_ud_delta_ = 0; 268 gesture_lr_delta_ = 0; 269 gesture_ud_count_ = 0; 270 gesture_lr_count_ = 0; 271 gesture_near_count_ = 0; 272 gesture_far_count_ = 0; 273 gesture_state_ = 0; 274 gesture_motion_ = DIR_NONE; 275 } 276 277 /** 278 * @brief IIC 读取一个byte 279 * 280 * @param reg 281 * @param val 282 * @return true 283 * @return false 284 */ 285 int8_t wire_read_data_byte(uint8_t reg,uint8_t *val) 286 { 287 char buf[256] = {0}; 288 struct i2c_client client = {0}; 289 client.flags = 1; 290 client.addr = APDS9960_I2C_ADDR; 291 strcpy(client.name,"apds9960"); 292 buf[0] = reg; 293 i2c_master_recv(IIC1,&client,buf,2); 294 *val = buf[0]; 295 delay_ms(5); 296 return RETURN_OK; 297 } 298 299 /** 300 * @brief IIC 写入一个byte 301 * 302 * @param reg 303 * @param val 304 * @return true 305 * @return false 306 */ 307 int8_t wire_write_data_byte(uint8_t reg,uint8_t val) 308 { 309 char buf[256] = {0}; 310 struct i2c_client client = {0}; 311 client.flags = 0; 312 client.addr = APDS9960_I2C_ADDR; 313 strcpy(client.name,"apds9960"); 314 buf[0] = reg; 315 buf[1] = val; 316 i2c_master_send(IIC1,&client,buf,2); 317 delay_ms(5); 318 return RETURN_OK; 319 } 320 321 /** 322 * @brief IIC 读取多个byte 323 * 324 * @param reg 325 * @param data 326 * @param len 327 * @return int8_t 328 */ 329 int8_t wire_read_data_block(uint8_t reg,uint8_t *data,uint32_t len) 330 { 331 char buf[256] = {0}; 332 struct i2c_client client = {0}; 333 client.flags = 1; 334 client.addr = APDS9960_I2C_ADDR; 335 strcpy(client.name,"apds9960"); 336 buf[0] = reg; 337 i2c_master_recv(IIC1,&client,buf,len + 1); 338 memcpy(data,buf,len); 339 delay_ms(5); 340 return len; 341 } 342 343 /** 344 * @brief IIC 写入多个byte 345 * 346 * @param reg 347 * @param data 348 * @param len 349 * @return int8_t 350 */ 351 int8_t wire_write_data_block(uint8_t reg,uint8_t *data,uint32_t len) 352 { 353 char buf[256] = {0}; 354 struct i2c_client client = {0}; 355 client.flags = 0; 356 client.addr = APDS9960_I2C_ADDR; 357 strcpy(client.name,"apds9960"); 358 buf[0] = reg; 359 strncpy(&buf[1],(char const*)data,len); 360 i2c_master_send(IIC1,&client,buf,len + 1); 361 delay_ms(5); 362 return len; 363 } 364 365 /** 366 * @brief Reads and returns the contents of the ENABLE register 367 * 368 * @return Contents of the ENABLE register. 0xFF if error. 369 */ 370 uint8_t get_mode(void) 371 { 372 uint8_t enable_value; 373 374 /* Read current ENABLE register */ 375 if( !wire_read_data_byte(APDS9960_ENABLE, &enable_value) ) 376 { 377 return ERROR; 378 } 379 380 return enable_value; 381 } 382 383 /** 384 * @brief Enables or disables a feature in the APDS-9960 385 * 386 #define POWER 0 387 #define AMBIENT_LIGHT 1 388 #define PROXIMITY 2 389 #define WAIT 3 390 #define AMBIENT_LIGHT_INT 4 391 #define PROXIMITY_INT 5 392 #define GESTURE 6 393 #define ALL 7 394 * @param[in] mode which feature to enable 395 * @param[in] enable ON (1) or OFF (0) 396 * @return True if operation success. False otherwise. 397 mode = ALL 7 enable = OFF 0 398 */ 399 int8_t set_mode(int8_t mode, uint8_t enable) 400 { 401 uint8_t reg_val; 402 403 /* Read current ENABLE register */ 404 reg_val = get_mode(); 405 mprintf("First_setMode_regval = %.2x\n",reg_val);//打印读取到的使能寄存器的值 0x80 = 0x4d 406 if( reg_val == ERROR ) {//如果读取到的值为0xFF,则错误 407 return RETURN_ERR; 408 } 409 410 /* Change bit(s) in ENABLE register */ 411 enable = enable & 0x01; 412 if((mode >= 0) && (mode <= 6)) //使能或失能某个位 413 { 414 if(enable) //使能 415 { 416 reg_val |= (1 << mode); 417 } 418 else //失能 419 { 420 reg_val &= ~(1 << mode); 421 } 422 } 423 else if( mode == ALL ) //使能全部 424 { 425 if (enable) 426 { 427 reg_val = 0x7F;//0x80=0x7F 全部使能 428 } 429 else //全部使能 430 { 431 reg_val = 0x00;//0x80=0x00 432 mprintf("0x80 = 0x00 all disable\n"); 433 } 434 } 435 436 mprintf("Last_setMode_regval = %.2x\n",reg_val);//打印读取到的使能寄存器的值 0x80 = 0x4d 437 /* Write value back to ENABLE register */ 438 if( !wire_write_data_byte(APDS9960_ENABLE, reg_val) ) 439 { 440 return RETURN_ERR; 441 } 442 443 return RETURN_OK; 444 } 445 446 /** 447 * @brief Determines if there is a gesture available for reading 448 * 确定是否有用于阅读的手势 449 * @return True if gesture available. False otherwise. 450 */ 451 int8_t is_gesture_available(void) 452 { 453 uint8_t val; 454 455 /*读0xAF*/ 456 if( !wire_read_data_byte(APDS9960_GSTATUS, &val) ) 457 { 458 return ERROR; 459 } 460 mprintf("AF_val = 0x%.2x\n",val); 461 /* Shift and mask out GVALID bit */ 462 val &= APDS9960_GVALID;//判断0xAF最低位GVALID是否为1 463 464 /* Return RETURN_OK/RETURN_ERR based on GVALID bit */ 465 if( val == 1) 466 { 467 return RETURN_OK; 468 } 469 else 470 { 471 return RETURN_ERR; 472 } 473 } 474 475 /** 476 * 处理原始手势数据确定滑动方向 477 * 478 * @return True if near or far state seen. False otherwise. 479 */ 480 int8_t process_gesture_data(void) 481 { 482 uint8_t u_first = 0; 483 uint8_t d_first = 0; 484 uint8_t l_first = 0; 485 uint8_t r_first = 0; 486 uint8_t u_last = 0; 487 uint8_t d_last = 0; 488 uint8_t l_last = 0; 489 uint8_t r_last = 0; 490 int ud_ratio_first; 491 int lr_ratio_first; 492 int ud_ratio_last; 493 int lr_ratio_last; 494 int ud_delta; 495 int lr_delta; 496 int i; 497 498 /* If we have less than 4 total gestures, that\'s not enough */ 499 if( gesture_data_.total_gestures <= 4 ) 500 { 501 return RETURN_ERR; 502 } 503 504 /* Check to make sure our data isn\'t out of bounds */ 505 if( (gesture_data_.total_gestures <= 32) && \ 506 (gesture_data_.total_gestures > 0) ) 507 { 508 509 /* Find the first value in U/D/L/R above the threshold */ 510 for( i = 0; i < gesture_data_.total_gestures; i++ ) 511 { 512 if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) && 513 (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) && 514 (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) && 515 (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) 516 { 517 518 u_first = gesture_data_.u_data[i]; 519 d_first = gesture_data_.d_data[i]; 520 l_first = gesture_data_.l_data[i]; 521 r_first = gesture_data_.r_data[i]; 522 #if DEBUG 523 mprintf("*********************************************\n"); 524 mprintf("Finding first:\n"); 525 mprintf("u_first = %d\n",u_first); 526 mprintf("d_first = %d\n",d_first); 527 mprintf("l_first = %d\n",l_first); 528 mprintf("r_first = %d\n",r_first); 529 mprintf("First i = %d\n",i); 530 mprintf("*********************************************\n"); 531 #endif 532 break; 533 } 534 } 535 /* If one of the _first values is 0, then there is no good data */ 536 if( (u_first == 0) || (d_first == 0) || \ 537 (l_first == 0) || (r_first == 0) ) 538 { 539 540 return RETURN_ERR; 541 } 542 /* Find the last value in U/D/L/R above the threshold */ 543 for( i = gesture_data_.total_gestures - 1; i >= 0; i-- ) 544 { 545 if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) && 546 (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) && 547 (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) && 548 (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) 549 { 550 551 u_last = gesture_data_.u_data[i]; 552 d_last = gesture_data_.d_data[i]; 553 l_last = gesture_data_.l_data[i]; 554 r_last = gesture_data_.r_data[i]; 555 #if DEBUG 556 mprintf("*********************************************\n"); 557 mprintf("Finding last:\n"); 558 mprintf("u_last = %d\n",u_last); 559 mprintf("d_last = %d\n",d_last); 560 mprintf("l_last = %d\n",l_last); 561 mprintf("r_last = %d\n",r_last); 562 mprintf("Last i = %d\n",i); 563 mprintf("*********************************************\n"); 564 #endif 565 break; 566 } 567 } 568 } 569 570 /* Calculate the first vs. last ratio of up/down and left/right */ 571 ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first); 572 lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first); 573 ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last); 574 lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last); 575 576 #if DEBUG 577 mprintf("===============================================\n"); 578 mprintf("first vs last ratio :\n"); 579 mprintf("ud_ratio_first = %d\n",ud_ratio_first); 580 mprintf("lr_ratio_first = %d\n",lr_ratio_first); 581 mprintf("ud_ratio_last = %d\n",ud_ratio_last); 582 mprintf("lr_ratio_last = %d\n",lr_ratio_last); 583 mprintf("===============================================\n"); 584 #endif 585 /* Determine the difference between the first and last ratios */ 586 ud_delta = ud_ratio_last - ud_ratio_first; 587 lr_delta = lr_ratio_last - lr_ratio_first; 588 #if DEBUG 589 590 mprintf("===============================================\n"); 591 mprintf("Delta:\n"); 592 mprintf("ud_delta = %d\n",ud_delta); 593 mprintf("lr_delta = %d\n",lr_delta); 594 mprintf("===============================================\n"); 595 #endif 596 597 /* Accumulate the UD and LR delta values */ 598 gesture_ud_delta_ += ud_delta; 599 gesture_lr_delta_ += lr_delta; 600 601 #if DEBUG 602 mprintf("===============================================\n"); 603 mprintf("Accumulate Delta:\n"); 604 mprintf("gesture_ud_delta_ = %d\n",gesture_ud_delta_); 605 mprintf("gesture_lr_delta_ = %d\n",gesture_lr_delta_); 606 mprintf("===============================================\n"); 607 #endif 608 /* Determine U/D gesture */ 609 if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) //50 610 { 611 gesture_ud_count_ = 1;//U-->D 612 mprintf("U--->D\n"); 613 } 614 else if( gesture_ud_delta_ <= -GESTURE_SENSITIVITY_1 ) 615 { 616 gesture_ud_count_ = -1; 617 mprintf("D--->U\n"); 618 } 619 else 620 { 621 gesture_ud_count_ = 0; 622 } 623 624 /* Determine L/R gesture */ 625 if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) 626 { 627 gesture_lr_count_ = 1; 628 mprintf("L--->R\n"); 629 } 630 else if( gesture_lr_delta_ <= -GESTURE_SENSITIVITY_1 ) 631 { 632 gesture_lr_count_ = -1; 633 mprintf("R--->L\n"); 634 } 635 else 636 { 637 gesture_lr_count_ = 0; 638 } 639 /* Determine Near/Far gesture */ 640 if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 0) ) 641 { 642 if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) //20 643 { 644 if( (ud_delta == 0) && (lr_delta == 0) ) 645 { 646 gesture_near_count_++; 647 } 648 else if( (ud_delta != 0) || (lr_delta != 0) ) 649 { 650 gesture_far_count_++; 651 } 652 653 if( (gesture_near_count_ >= 10) && (gesture_far_count_ >= 2) ) 654 { 655 if( (ud_delta == 0) && (lr_delta == 0) ) 656 { 657 gesture_state_ = NEAR_STATE; 658 } 659 else if( (ud_delta != 0) && (lr_delta != 0) ) 660 { 661 gesture_state_ = FAR_STATE; 662 } 663 return RETURN_OK; 664 } 665 } 666 } 667 else 668 { 669 if( (abs((int)ud_delta) < GESTURE_SENSITIVITY_2) && (abs((int)lr_delta) < GESTURE_SENSITIVITY_2) ) 670 { 671 672 if( (ud_delta == 0) && (lr_delta == 0) ) 673 { 674 gesture_near_count_++; 675 } 676 677 if( gesture_near_count_ >= 10 ) 678 { 679 gesture_ud_count_ = 0; 680 gesture_lr_count_ = 0; 681 gesture_ud_delta_ = 0; 682 gesture_lr_delta_ = 0; 683 } 684 } 685 } 686 #if DEBUG 687 mprintf("===============================================\n"); 688 mprintf("UD_CT = %d\n",gesture_ud_count_); 689 mprintf("LR_CT = %d\n",gesture_lr_count_); 690 mprintf("NEAR_CT = %d\n",gesture_near_count_); 691 mprintf("FAR_CT = %d\n",gesture_far_count_); 692 mprintf("===============================================\n"); 693 #endif 694 return RETURN_ERR; 695 } 696 697 /** 698 * 确定滑动方向、远近状态 699 * 700 * @return True if near/far event. False otherwise. 701 */ 702 int8_t decode_gesture(void) 703 { 704 /* Return if near or far event is detected */ 705 if( gesture_state_ == NEAR_STATE ) //手势状态 = 进距离 706 { 707 gesture_motion_ = DIR_NEAR; 708 return RETURN_OK; 709 } 710 else if ( gesture_state_ == FAR_STATE ) //手势状态 = 远距离 711 { 712 gesture_motion_ = DIR_FAR; 713 return RETURN_OK; 714 } 715 716 /* Determine swipe direction 确定滑动方向 */ 717 if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) 718 { 719 gesture_motion_ = DIR_UP; 720 } 721 else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 0) ) 722 { 723 gesture_motion_ = DIR_DOWN; 724 } 725 else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 1) ) 726 { 727 gesture_motion_ = DIR_RIGHT; 728 } 729 else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == -1) ) 730 { 731 gesture_motion_ = DIR_LEFT; 732 } 733 else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 1) ) 734 { 735 if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) 736 { 737 gesture_motion_ = DIR_UP; 738 } 739 else 740 { 741 gesture_motion_ = DIR_RIGHT; 742 } 743 } 744 else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == -1) ) 745 { 746 if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) 747 { 748 gesture_motion_ = DIR_DOWN; 749 } 750 else 751 { 752 gesture_motion_ = DIR_LEFT; 753 } 754 } 755 else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == -1) ) 756 { 757 if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) 758 { 759 gesture_motion_ = DIR_UP; 760 } 761 else 762 { 763 gesture_motion_ = DIR_LEFT; 764 } 765 } 766 else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 1) ) 767 { 768 if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) 769 { 770 gesture_motion_ = DIR_DOWN; 771 } 772 else 773 { 774 gesture_motion_ = DIR_RIGHT; 775 } 776 } 777 else 778 { 779 return RETURN_ERR; 780 } 781 return RETURN_OK; 782 } 783 784 /******************************************************************************* 785 * High-level gesture controls 786 ******************************************************************************/ 787 788 /** 789 * @brief Resets all the parameters in the gesture data member 790 */ 791 void reset_gesture_parameters(void) 792 { 793 gesture_data_.index = 0; 794 gesture_data_.total_gestures = 0; 795 796 gesture_ud_delta_ = 0; 797 gesture_lr_delta_ = 0; 798 799 gesture_ud_count_ = 0; 800 gesture_lr_count_ = 0; 801 802 gesture_near_count_ = 0; 803 gesture_far_count_ = 0; 804 805 gesture_state_ = 0; 806 gesture_motion_ = DIR_NONE; 807 } 808 809 /** 810 * @brief Processes a gesture event and returns best guessed gesture 811 * 处理一个手势事件并返回最佳猜测手势 812 * @return Number corresponding to gesture. -1 on error. 813 */ 814 int read_gesture(void) 815 { 816 uint8_t fifo_level = 0; 817 int8_t bytes_read = 0; 818 uint8_t fifo_data[128]; 819 uint8_t gstatus; 820 int motion; 821 int i; 822 823 /* Get the contents of the STATUS register. Is data still valid? */ 824 if( !wire_read_data_byte(APDS9960_GSTATUS, &gstatus) ) 825 { 826 return ERROR; 827 } 828 /* Make sure that power and gesture is on and data is valid */ 829 if(!is_gesture_available()||!(get_mode() & 0x41) ) 830 { 831 return DIR_NONE; 832 } 833 834 /* Keep looping as long as gesture data is valid */ 835 while(1) 836 { 837 /* Wait some time to collect next batch of FIFO data */ 838 delay_ms(FIFO_PAUSE_TIME); 839 840 /* Get the contents of the STATUS register. Is data still valid? */ 841 if( !wire_read_data_byte(APDS9960_GSTATUS, &gstatus) ) 842 { 843 return ERROR; 844 } 845 mprintf("gstatus = %.2x\n",gstatus); 846 847 /* If we have valid data, read in FIFO */ 848 if((gstatus & APDS9960_GVALID) == APDS9960_GVALID) 849 { 850 851 /* Read the current FIFO level */ 852 if( !wire_read_data_byte(APDS9960_GFLVL, &fifo_level) ) 853 { 854 return ERROR; 855 } 856 /* If there\'s stuff in the FIFO, read it into our data block */ 857 if( fifo_level > 0) 858 { 859 bytes_read = wire_read_data_block( APDS9960_GFIFO_U, 860 (uint8_t*)fifo_data, 861 (fifo_level * 4) ); 862 863 #if DEBUG 864 for(i = 0;i < fifo_level * 4;i = i + 4) 865 { 866 mprintf("=========================\n"); 867 mprintf("%d fifo_level data\n",i/4); 868 mprintf("U = 0x%.2x ",fifo_data[i+0]); 869 mprintf("D = 0x%.2x ",fifo_data[i+1]); 870 mprintf("L = 0x%.2x ",fifo_data[i+2]); 871 mprintf("R = 0x%.2x \n",fifo_data[i+3]); 872 mprintf("=========================\n"); 873 } 874 mprintf("fifo_level = %d\n",fifo_level); 875 mprintf("bytes_read = %d\n",bytes_read); 876 #endif 877 if(bytes_read == -1) 878 { 879 return ERROR; 880 } 881 882 /* If at least 1 set of data, sort the data into U/D/L/R */ 883 if( bytes_read >= 4 ) 884 { 885 for( i = 0; i < bytes_read; i += 4 ) 886 { 887 gesture_data_.u_data[gesture_data_.index] = \ 888 fifo_data[i + 0]; 889 gesture_data_.d_data[gesture_data_.index] = \ 890 fifo_data[i + 1]; 891 gesture_data_.l_data[gesture_data_.index] = \ 892 fifo_data[i + 2]; 893 gesture_data_.r_data[gesture_data_.index] = \ 894 fifo_data[i + 3]; 895 gesture_data_.index++; 896 gesture_data_.total_gestures++; 897 } 898 mprintf("gesture_data_.index = %d\n",gesture_data_.index); 899 mprintf("gesture_data_.total_gestures = %d\n",gesture_data_.total_gestures); 900 901 /* Filter and process gesture data. Decode near/far state */ 902 if(process_gesture_data() ) 903 { 904 if(decode_gesture() ) 905 { 906 mprintf("gesture_motion_ = %d\n",gesture_motion_); 907 } 908 } 909 910 /* Reset data */ 911 gesture_data_.index = 0; 912 gesture_data_.total_gestures = 0; 913 } 914 } 915 } 916 else 917 { 918 /* Determine best guessed gesture and clean up */ 919 delay_ms(FIFO_PAUSE_TIME); 920 decode_gesture(); 921 motion = gesture_motion_; 922 reset_gesture_parameters(); 923 return motion; 924 } 925 } 926 } 927 928 /** 929 * Turn the APDS-9960 on 930 * 931 * @return True if operation successful. False otherwise. 932 */ 933 int8_t enable_power(void) 934 { 935 if( !set_mode(POWER, 1) ) 936 { 937 return RETURN_ERR; 938 } 939 940 return RETURN_OK; 941 } 942 943 /** 944 * Turn the APDS-9960 off 945 * 946 * @return True if operation successful. False otherwise. 947 */ 948 int8_t disable_power(void) 949 { 950 if( !set_mode(POWER, 0) ) 951 { 952 return RETURN_ERR; 953 } 954 955 return RETURN_OK; 956 } 957 958 /** 959 * @brief Sets the LED current boost value 960 * 设置LED当前的升压值 961 * Value Boost Current 962 * 0 100% 963 * 1 150% 964 * 2 200% 965 * 3 300% 966 * 967 * @param[in] drive the value (0-3) for current boost (100-300%) 968 * @return True if operation successful. False otherwise. 969 */ 970 int8_t set_led_boost(uint8_t boost) 971 { 972 uint8_t val; 973 974 /* Read value from CONFIG2 register */ 975 if( !wire_read_data_byte(APDS9960_CONFIG2, &val) ) { 976 return RETURN_ERR; 977 } 978 979 /* Set bits in register to given value */ 980 boost &= 0x03; 981 boost = boost << 4; 982 val &= 0xCF; 983 val |= boost; 984 985 /* Write register value back into CONFIG2 register */ 986 if( !wire_write_data_byte(APDS9960_CONFIG2, val) ) { 987 return RETURN_ERR; 988 } 989 990 return RETURN_OK; 991 } 992 993 994 995 996 997 /*********************************************************************************** 998 设置手势接近进入阀值 999 APDS9960_GPENTH = threshold = 40 1000 0xA0 = 40 1001 0xA0的bit4必须设为0 1002 手势接近阀值会与接近数据PDATA进行比较并决定是否进入手势状态机 1003 ***********************************************************************************/ 1004 int8_t set_gesture_enter_thresh(uint8_t threshold) 1005 { 1006 if( !wire_write_data_byte(APDS9960_GPENTH, threshold) ) 1007 { 1008 return RETURN_ERR; 1009 } 1010 1011 return RETURN_OK; 1012 } 1013 1014 1015 /*********************************************************************************** 1016 设置手势接近退出阀值 1017 APDS9960_GEXTH = threshold = 30 1018 0xA1 = 30 1019 此寄存器设置阀值决定手势结束,同时退出手势状态机. 1020 设置GTHR_OUT为0x00会防止手势退出直到GMODE被设为0 1021 ***********************************************************************************/ 1022 int8_t set_gesture_exit_thresh(uint8_t threshold) 1023 { 1024 if( !wire_write_data_byte(APDS9960_GEXTH, threshold) ) { 1025 return RETURN_ERR; 1026 } 1027 1028 return RETURN_OK; 1029 } 1030 1031 1032 1033 /** 1034 * @brief Sets the gain of the photodiode during gesture mode 1035 gain = 2 1036 保留 7 写0 1037 GGAIN 6:5 手势增益控制,设定一个增益手势接收在手势模式下 1038 0 1x 1039 1 2x 1040 2 4x 1041 3 8x 1042 GLDRIVE 4:3 手势LED驱动强度 1043 0 100ma 1044 1 50ma 1045 2 25ma 1046 3 12.5ma 1047 GWTIME 2:0 手势等待时间 1048 0 0ms 1049 1 2.8ms 1050 2 5.6ms 1051 3 8.4ms 1052 4 14.0ms 1053 5 22.4ms 1054 6 30.8ms 1055 7 39.2ms 1056 */ 1057 int8_t set_gesture_gain(uint8_t gain) 1058 { 1059 uint8_t val; 1060 1061 /* Read value from GCONF2 register */ 1062 if( !wire_read_data_byte(APDS9960_GCONF2, &val) ) 1063 { 1064 return RETURN_ERR; 1065 } 1066 /* Set bits in register to given value */ 1067 gain &= 0x03;//取gain最低两位 1068 gain = gain << 5;//移动到6:5 1069 val &= 0x9F;//将6:5位清零 1070 val |= gain;//将gain的6:5位赋值给val 1071 /* 然后在将val写入配置寄存器2设置增益(即用gain给其设置增益)*/ 1072 if( !wire_write_data_byte(APDS9960_GCONF2, val) ) 1073 { 1074 return RETURN_ERR; 1075 } 1076 1077 return RETURN_OK; 1078 } 1079 1080 1081 1082 /** 1083 * @brief Sets the LED drive current during gesture mode 1084 * 1085 * Value LED Current 1086 * 0 100 mA 1087 * 1 50 mA 1088 * 2 25 mA 1089 * 3 12.5 mA 1090 * 1091 * @param[in] drive the value for the LED drive current 1092 * @return True if operation successful. False otherwise. 1093 */ 1094 int8_t set_gesture_led_drive(uint8_t drive) 1095 { 1096 uint8_t val; 1097 1098 /* Read value from GCONF2 register */ 1099 if( !wire_read_data_byte(APDS9960_GCONF2, &val) ) 1100 { 1101 return RETURN_ERR; 1102 } 1103 /* Set bits in register to given value */ 1104 drive &= 0x03; 1105 drive = drive << 3;//bit 4:3 1106 val &= 0xE7; 1107 val |= drive; 1108 /* Write register value back into GCONF2 register */ 1109 if( !wire_write_data_byte(APDS9960_GCONF2, val) ) 1110 { 1111 return RETURN_ERR; 1112 } 1113 1114 return RETURN_OK; 1115 } 1116 1117 1118 1119 /** 1120 * @brief Sets the time in low power mode between gesture detections 1121 * 1122 * Value Wait time 1123 * 0 0 ms 1124 * 1 2.8 ms 1125 * 2 5.6 ms 1126 * 3 8.4 ms 1127 * 4 14.0 ms 1128 * 5 22.4 ms 1129 * 6 30.8 ms 1130 * 7 39.2 ms 1131 * 1132 * @param[in] the value for the wait time 1133 * @return True if operation successful. False otherwise. 1134 */ 1135 int8_t set_gesture_wait_time(uint8_t time) 1136 { 1137 uint8_t val; 1138 1139 /* Read value from GCONF2 register */ 1140 if( !wire_read_data_byte(APDS9960_GCONF2, &val)) 1141 { 1142 return RETURN_ERR; 1143 } 1144 mprintf("First_WaitTime__0xA3 = %.2x\n",val); 1145 1146 /* Set bits in register to given value */ 1147 time &= 0x07; 1148 val &= 0xF8; 1149 val |= time; 1150 1151 /* Write register value back into GCONF2 register */ 1152 if( !wire_write_data_byte(APDS9960_GCONF2, val) ) 1153 { 1154 return RETURN_ERR; 1155 } 1156 mprintf("Last_WaitTime__0xA3 = %.2x\n",val); 1157 return RETURN_OK; 1158 } 1159 1160 1161 1162 1163 /** 1164 * @brief Turns gesture-related interrupts on or off 1165 * 1166 * @param[in] enable 1 to enable interrupts, 0 to turn them off 1167 * @return True if operation successful. False otherwise. 1168 */ 1169 int8_t set_gesture_int_enable(uint8_t enable) 1170 { 1171 uint8_t val; 1172 1173 /* Read value from GCONF4 register */ 1174 if( !wire_read_data_byte(APDS9960_GCONF4, &val) ) 1175 { 1176 return RETURN_ERR; 1177 } 1178 mprintf("First_GIEN__0xAB = %.2x\n",val); 1179 /* Set bits in register to given value */ 1180 enable &= 0x01; 1181 enable = enable << 1; 1182 val &= 0xFD; 1183 val |= enable; 1184 mprintf("Last_GIEN__0xAB = %.2x\n",val); 1185 /* Write register value back into GCONF4 register */ 1186 if( !wire_write_data_byte(APDS9960_GCONF4, val) ) 1187 { 1188 return RETURN_ERR; 1189 } 1190 1191 return RETURN_OK; 1192 } 1193 1194 1195 1196 1197 /** 1198 * @brief Tells the state machine to either enter or exit gesture state machine 1199 * 1200 * @param[in] mode 1 to enter gesture state machine, 0 to exit. 1201 * @return True if operation successful. False otherwise. 1202 */ 1203 int8_t set_gesture_mode(uint8_t mode) 1204 { 1205 uint8_t val; 1206 1207 /* Read value from GCONF4 register */ 1208 if( !wire_read_data_byte(APDS9960_GCONF4, &val) ) 1209 { 1210 return RETURN_ERR; 1211 } 1212 1213 /* Set bits in register to given value */ 1214 mode &= 0x01; 1215 val &= 0xFE; 1216 val |= mode; 1217 1218 /* Write register value back into GCONF4 register */ 1219 if( !wire_write_data_byte(APDS9960_GCONF4, val) ) { 1220 return RETURN_ERR; 1221 } 1222 1223 return RETURN_OK; 1224 } 1225 1226 /** 1227 * @brief Configures I2C communications and initializes registers to defaults 1228 * 1229 * @return True if initialized successfully. False otherwise. 1230 */ 1231 int8_t spark_fun_apds9960_init(void) 1232 { 1233 uint8_t id,pid; 1234 1235 /* 读取器件ID 0x92 = 0xAB */ 1236 if( !wire_read_data_byte(APDS9960_ID,&pid) ) 1237 { 1238 return RETURN_ERR; 1239 } 1240 id = pid; 1241 mprintf("ID:0x%x\n",id); 1242 if( !((id == APDS9960_ID_1 || id == APDS9960_ID_2)) ) 1243 { 1244 return RETURN_ERR; 1245 } 1246 /* 失能失能寄存器0x80 = 0x00 */ 1247 if( !set_mode(ALL, OFF) ) //(7,0) 1248 { 1249 return RETURN_ERR; 1250 } 1251 //设置手势接近进入(手势状态机)阀值为0xA0 = 40 1252 /* 设置手势传感器寄存器默认值 */ 1253 if( !set_gesture_enter_thresh(DEFAULT_GPENTH) ) 1254 { 1255 return RETURN_ERR; 1256 } 1257 //设置手势接近退出(手势状态机)阀值为0xA1 = 30 1258 if( !set_gesture_exit_thresh(DEFAULT_GEXTH) ) 1259 { 1260 return RETURN_ERR; 1261 } 1262 //设置配置寄存器1 0xA2 = 0x40 1263 //1.在4个数据集被添加到FIFO里后产生中断 1264 //2.All UDLR 探测数据被包含到集合中 1265 //3.手势退出持久性.当连续的手势结束发生称为比GEXPERS大于或等于的值时, 1266 // 手势状态机退出(第1个手势结束发生导致手势状态机退出) 1267 if( !wire_write_data_byte(APDS9960_GCONF1, DEFAULT_GCONF1) ) 1268 { 1269 return RETURN_ERR; 1270 } 1271 //设置配置寄存器2 0xA3 的 bit 6:5 = 10 4x增益 1272 if( !set_gesture_gain(DEFAULT_GGAIN) ) 1273 { 1274 return RETURN_ERR; 1275 } 1276 //设置配置寄存器2 0xA3 的 bit 4:3 = 00 100ma 1277 if( !set_gesture_led_drive(DEFAULT_GLDRIVE) ) 1278 { 1279 return RETURN_ERR; 1280 } 1281 //设定配置寄存器2 0xA3 的 bit 2:0=001 2.8ms 1282 if( !set_gesture_wait_time(DEFAULT_GWTIME) ) 1283 { 1284 return RETURN_ERR; 1285 } 1286 //设置手势UP偏移寄存器 0xA4 = 0 没有偏移 1287 if( !wire_write_data_byte(APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ) 1288 { 1289 return RETURN_ERR; 1290 } 1291 //设置手势DOWN偏移寄存器 0xA5 = 0 没有偏移 1292 if( !wire_write_data_byte(APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ) 1293 { 1294 return RETURN_ERR; 1295 } 1296 //设置手势LEFT偏移寄存器 0xA7 = 0 没有偏移 1297 if( !wire_write_data_byte(APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ) 1298 { 1299 return RETURN_ERR; 1300 } 1301 //设置手势RIGHT偏移寄存器 0xA9 = 0 没有偏移 1302 if( !wire_write_data_byte(APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ) 1303 { 1304 return RETURN_ERR; 1305 } 1306 //设置收势脉冲数和脉宽寄存器0xA6 = 0xC9 32us, 10 pulses 1307 if( !wire_write_data_byte(APDS9960_GPULSE, DEFAULT_GPULSE) ) 1308 { 1309 return RETURN_ERR; 1310 } 1311 //设置配置寄存器3 0xAA 的bit 1:0 = 00 所有光电二极管在手势期间均有效 1312 if( !wire_write_data_byte(APDS9960_GCONF3, DEFAULT_GCONF3) ) 1313 { 1314 return RETURN_ERR; 1315 } 1316 //设置配置寄存器4 0xAB 的bit1 = 0 关闭手势中断 GIEN=0 1317 if( !set_gesture_int_enable(DEFAULT_GIEN) ) 1318 { 1319 return RETURN_ERR; 1320 } 1321 return RETURN_OK; 1322 } 1323 1324 /** 1325 * @brief Starts the gesture recognition engine on the APDS-9960 1326 * 在ap9960上启动手势识别引擎 1327 * @param[in] interrupts RETURN_OK to enable hardware external interrupt on gesture 1328 * @return True if engine enabled correctly. False on error. 1329 */ 1330 int8_t enable_gesture_sensor(int8_t interrupts) 1331 { 1332 /* Enable gesture mode 1333 Set ENABLE to 0 (power off) 1334 Set WTIME to 0xFF 1335 Set AUX to LED_BOOST_300 1336 Enable PON, WEN, PEN, GEN in ENABLE 1337 */ 1338 //interrupts = RETURN_OK; 1339 1340 reset_gesture_parameters();//复位手势变量=0 1341 1342 //设置等待时间寄存器0x83 = 0xFF (WLONG=1 0.03s) (WLONG=0 2.78ms) 1343 if( !wire_write_data_byte(APDS9960_WTIME, 0xFF) ) // 1344 { 1345 return RETURN_ERR; 1346 } 1347 1348 //设置接近脉冲计数寄存器 0x8E = 0x89 16us, 10 pulses 1349 if( !wire_write_data_byte(APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ) 1350 { 1351 return RETURN_ERR; 1352 } 1353 1354 //设置配置寄存器2 0x90的bit5:4=11 %300 LED驱动电流 1355 if( !set_led_boost(LED_BOOST_300) ) 1356 { 1357 return RETURN_ERR; 1358 } 1359 1360 //是否开启手势中断配置寄存器4 0xAB 1361 if( interrupts ) 1362 { 1363 if( !set_gesture_int_enable(1) ) 1364 { 1365 return RETURN_ERR; 1366 } 1367 } 1368 else 1369 { 1370 if( !set_gesture_int_enable(0) ) 1371 { 1372 return RETURN_ERR; 1373 } 1374 } 1375 1376 //设置手势模式GMODE = 1 1377 if( !set_gesture_mode(1) ) 1378 { 1379 return RETURN_ERR; 1380 } 1381 1382 //PON = 1 0x80 的 bit0 = 1 1383 if( !enable_power() ) 1384 { 1385 return RETURN_ERR; 1386 } 1387 1388 //WEN = 1 0x80 的 bit3 = 1 1389 if( !set_mode(WAIT, 1) ) 1390 { 1391 return RETURN_ERR; 1392 } 1393 1394 //PEN=1 0x80 的 bit2 = 1 1395 if( !set_mode(PROXIMITY, 1) ) 1396 { 1397 return RETURN_ERR; 1398 } 1399 1400 //PIEN=1 0x80 的 bit6 = 1 1401 if( !set_mode(GESTURE, 1) ) 1402 { 1403 return RETURN_ERR; 1404 } 1405 1406 return RETURN_OK; 1407 } 1408 1409 /** 1410 * @brief APDS-9960 init 1411 * 1412 */ 1413 int32_t apds9960_open(void) 1414 { 1415 Scu_SetIOReuse(UART1_TX_PAD,FIRST_FUNCTION); 1416 Scu_SetDeviceGate((unsigned int)GPIO0,ENABLE); 1417 Scu_Setdevice_Reset((unsigned int)GPIO0); 1418 Scu_Setdevice_ResetRelease((unsigned int)GPIO0); 1419 NVIC_EnableIRQ(GPIO0_IRQn); 1420 gpio_irq_trigger_config(GPIO0,gpio_pin_1,both_edges_trigger); 1421 1422 NVIC_EnableIRQ(IIC1_IRQn); 1423 Scu_SetDeviceGate((unsigned int)IIC1,ENABLE); 1424 Scu_Setdevice_Reset((unsigned int)IIC1); 1425 Scu_Setdevice_ResetRelease((unsigned int)IIC1); 1426 Scu_SetIOReuse(I2C1_SCL_PAD,FIRST_FUNCTION); 1427 Scu_SetIOReuse(I2C1_SDA_PAD,FIRST_FUNCTION); 1428 1429 I2C_InitStruct InitStruct = {0}; 1430 InitStruct.I2C_IO_BASE = (unsigned int)IIC1; 1431 InitStruct.I2C_CLOCK_SPEED = 400; 1432 InitStruct.I2C_INPUT_CLK = 50000000; 1433 InitStruct.TIMEOUT = 0X5FFFFF; 1434 i2c_init(IIC1,&InitStruct); 1435 /* 模块初始化,官方示例代码引用 */ 1436 sparkfun_apds9960(); 1437 1438 if(!spark_fun_apds9960_init()) 1439 { 1440 return RETURN_ERR; 1441 } 1442 if(!enable_gesture_sensor(RETURN_OK)) 1443 { 1444 return RETURN_ERR; 1445 } 1446 1447 return RETURN_OK; 1448 } 1449 1450 /** 1451 * @brief 中断回调函数 1452 * 1453 */ 1454 void apds9960_callback(void) 1455 { 1456 sensor_irq_inform(SENSOR_TYPE_GESTURE); 1457 } 1458 1459 /** 1460 * @brief 手势解析 1461 * 1462 */ 1463 void gesture_manage(void) 1464 { 1465 if(is_gesture_available()) 1466 { 1467 switch (read_gesture()) 1468 { 1469 case DIR_UP: 1470 mprintf("Gesture-UP\n"); 1471 break; 1472 case DIR_DOWN: 1473 mprintf("Gesture-DOWN\n"); 1474 break; 1475 case DIR_LEFT: 1476 mprintf("Gesture-LEFT\n"); 1477 break; 1478 case DIR_RIGHT: 1479 mprintf("Gesture-RIGHT\n"); 1480 break; 1481 case DIR_NEAR: 1482 mprintf("Gesture-NEAR\n"); 1483 break; 1484 case DIR_FAR: 1485 mprintf("Gesture-FAR\n"); 1486 break; 1487 default: 1488 mprintf("Gesture-NONE\n"); 1489 } 1490 } 1491 } 1492 1493 /** 1494 * @brief apds9960 ops 1495 * 1496 */ 1497 sensor_ops_t apds9960_ops = 1498 { 1499 apds9960_open, 1500 };
1 /** 2 * @file APDS_9960.h 3 * @brief APDS-9960传感器的头文件 4 * @version 0.1 5 * @date 2019-07-02 6 * 7 * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. 8 * 9 */ 10 11 #ifndef __APDS_9960_H__ 12 #define __APDS_9960_H__ 13 14 /** 15 * @ingroup third_device_driver 16 * @defgroup APDS9960 17 * @brief APDS9960传感器驱动 18 * @{ 19 */ 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /*----------------------------------------------------------------------------- 26 include 27 -----------------------------------------------------------------------------*/ 28 #include "ci_sensor.h" 29 30 /*----------------------------------------------------------------------------- 31 define 32 -----------------------------------------------------------------------------*/ 33 34 /*----------------------------------------------------------------------------- 35 extern 36 -----------------------------------------------------------------------------*/ 37 extern int abs(int __x); 38 extern sensor_ops_t apds9960_ops; 39 /*----------------------------------------------------------------------------- 40 struct / enum / union 41 -----------------------------------------------------------------------------*/ 42 43 /*----------------------------------------------------------------------------- 44 global 45 -----------------------------------------------------------------------------*/ 46 47 /*----------------------------------------------------------------------------- 48 function declare 49 -----------------------------------------------------------------------------*/ 50 void gesture_manage(void); 51 52 #ifdef __cplusplus 53 } 54 #endif 55 56 /** 57 * @} 58 */ 59 60 #endif 61 62 /*----------------------------------------------------------------------------- 63 end of the file 64 -----------------------------------------------------------------------------*/
版权声明:本文为wangyanwen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。