锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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

时间:2022-12-08 15:00:00 二极管1428675二极管736二极管1392传感器753a二极管1441二极管

传感器简介

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                   xFF
  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");
元器件数据手册、IC替代型号,打造电子元器件IC百科大全!
          

相关文章