传感器简介
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");
标签: 二极管1428675二极管736二极管1392传感器753a二极管1441二极管