APDS-9960手势检测、接近检测、数字环境光感(ALS)和色感(RGBC)传感器驱动(基于传感器管理组件)

传感器简介

APDS-9960传感器具有先进的手势检测、接近检测、数字环境光感(ALS)和色感(RGBC)。

APDS_9960.c

   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 };

APDS_9960.h

 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 -----------------------------------------------------------------------------*/

你可能感兴趣的:(APDS-9960手势检测、接近检测、数字环境光感(ALS)和色感(RGBC)传感器驱动(基于传感器管理组件))