1/* 2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited 3 */ 4 5/* 6The driver for AP3216C chip, The AP3216C is an integrated ALS & PS module 7that includes a digital ambient light sensor [ALS], a proximity sensor [PS], 8and an IR LED in a single package. 9*/ 10/* 11添加如下配置到app.json中: 12 "ap3216c": { 13 "type": "I2C", 14 "port": 1, 15 "addrWidth": 7, 16 "freq": 100000, 17 "mode": "master", 18 "devAddr": 30 19 } 20*/ 21// Require libjs/lib/i2c.js module. 22 23const AP3216C_I2C_PORT = 1 24const AP3216C_ADDR = 0x1e 25 26// System Register 27const AP3216C_SYS_CONFIGURATION_REG = 0x00 28const AP3216C_SYS_INT_STATUS_REG = 0x01 29const AP3216C_SYS_INT_CLEAR_MANNER_REG = 0x02 30const AP3216C_IR_DATA_L_REG = 0x0A 31const AP3216C_IR_DATA_H_REG = 0x0B 32const AP3216C_ALS_DATA_L_REG = 0x0C 33const AP3216C_ALS_DATA_H_REG = 0x0D 34const AP3216C_PS_DATA_L_REG = 0x0E 35const AP3216C_PS_DATA_H_REG = 0x0F 36 37// ALS Register 38const AP3216C_ALS_CONFIGURATION_REG = 0x10 39const AP3216C_ALS_CALIBRATION_REG = 0x19 40const AP3216C_ALS_THRESHOLD_LOW_L_REG = 0x1A 41const AP3216C_ALS_THRESHOLD_LOW_H_REG = 0x1B 42const AP3216C_ALS_THRESHOLD_HIGH_L_REG = 0x1C 43const AP3216C_ALS_THRESHOLD_HIGH_H_REG = 0x1D 44 45// PS Register 46const AP3216C_PS_CONFIGURATION_REG = 0x20 47const AP3216C_PS_LED_DRIVER_REG = 0x21 48const AP3216C_PS_INT_FORM_REG = 0x22 49const AP3216C_PS_MEAN_TIME_REG = 0x23 50const AP3216C_PS_LED_WAITING_TIME_REG = 0x24 51const AP3216C_PS_CALIBRATION_L_REG = 0x28 52const AP3216C_PS_CALIBRATION_H_REG = 0x29 53const AP3216C_PS_THRESHOLD_LOW_L_REG = 0x2A 54const AP3216C_PS_THRESHOLD_LOW_H_REG = 0x2B 55const AP3216C_PS_THRESHOLD_HIGH_L_REG = 0x2C 56const AP3216C_PS_THRESHOLD_HIGH_H_REG = 0x2D 57 58//mode value 59const AP3216C_MODE_POWER_DOWN = 0x0 60const AP3216C_MODE_ALS = 0x1 61const AP3216C_MODE_PS = 0x2 62const AP3216C_MODE_ALS_AND_PS = 0x3 63const AP3216C_MODE_SW_RESET = 0x4 64const AP3216C_MODE_ALS_ONCE = 0x5 65const AP3216C_MODE_PS_ONCE = 0x6 66const AP3216C_MODE_ALS_AND_PS_ONCE = 0x7 67 68//ap3216c_int_clear_manner 69const AP3216C_INT_CLEAR_MANNER_BY_READING = 0x0 70const AP3216C_ALS_CLEAR_MANNER_BY_SOFTWARE = 0x1 71 72//als_range 73const AP3216C_ALS_RANGE_20661 = 0x0 74const AP3216C_ALS_RANGE_5162 = 0x1 75const AP3216C_ALS_RANGE_1291 = 0x2 76const AP3216C_ALS_RANGE_323 = 0x3 77 78//als_range 79const AP3216C_PS_GAIN1 = 0x0 80const AP3216C_PS_GAIN2 = 0x1 81const AP3216C_PS_GAIN4 = 0x2 82const AP3216C_PS_GAIN8 = 0x3 83 84const AP3216C_SYSTEM_MODE = 0x0 85const AP3216C_INT_PARAM = 0x1 86const AP3216C_ALS_RANGE = 0x2 87const AP3216C_ALS_PERSIST = 0x3 88const AP3216C_ALS_CALIBRATION = 0x4 89const AP3216C_ALS_LOW_THRESHOLD_L = 0x5 90const AP3216C_ALS_LOW_THRESHOLD_H = 0x6 91const AP3216C_ALS_HIGH_THRESHOLD_L = 0x7 92const AP3216C_ALS_HIGH_THRESHOLD_H = 0x8 93const AP3216C_PS_INTEGRATED_TIME = 0x9 94const AP3216C_PS_GAIN = 0xa 95const AP3216C_PS_PERSIST = 0xb 96const AP3216C_PS_LED_CONTROL = 0xc 97const AP3216C_PS_LED_DRIVER_RATIO = 0xd 98const AP3216C_PS_INT_MODE = 0xe 99const AP3216C_PS_MEAN_TIME = 0xf 100const AP3216C_PS_WAITING_TIME = 0x10 101const AP3216C_PS_CALIBRATION_L = 0x11 102const AP3216C_PS_CALIBRATION_H = 0x12 103const AP3216C_PS_LOW_THRESHOLD_L = 0x13 104const AP3216C_PS_LOW_THRESHOLD_H = 0x14 105const AP3216C_PS_HIGH_THRESHOLD_L = 0x15 106const AP3216C_PS_HIGH_THRESHOLD_H = 0x16 107 108var i2c = require('i2c'); 109 110var ap3216cDev; 111 112function fakeSleep(ms) { 113 var date = new Date(); 114 var curDate; 115 do { 116 curDate = new Date(); 117 } while((curDate - date) < ms); 118} 119 120/* 写寄存器的值 */ 121function write_reg(addr, data) 122{ 123 var msgbuf = [data]; 124 ap3216cDev.writeMem(addr, msgbuf); 125 console.log("--> write addr " + addr + ", value = " + msgbuf); 126} 127 128/* 读寄存器的值 */ 129function read_regs(addr, len) 130{ 131 buf = ap3216cDev.readMem(addr, len); 132 console.log("--> read addr " + addr + ", value = " + buf); 133 return buf; 134} 135 136/* 软件复位传感器 */ 137function reset_sensor() 138{ 139 write_reg(AP3216C_SYS_CONFIGURATION_REG, AP3216C_MODE_SW_RESET); // reset 140} 141 142/** 143 * This function is convenient to getting data except including high and low 144 * data for this sensor. note:after reading lower register first,reading higher 145 * add one. 146 */ 147function read_low_and_high(reg, len) 148{ 149 var data; 150 var buf0; 151 var buf1; 152 153 buf0 = read_regs(reg, len); // 读低字节 154 buf1 = read_regs(reg + 1, len); // 读高字节 155 data = buf0 | (buf1 << len * 8); // 合并数据 156 data = data >>> 0 157 158 return data; 159} 160 161/** 162 * This function reads status register by ap3216c sensor measurement 163 * 164 * @param no 165 * 166 * @return status register value. 167 */ 168 169function ap3216c_get_IntStatus() 170{ 171 var IntStatus; 172 173 /* 读中断状态寄存器 */ 174 175 IntStatus = read_regs(AP3216C_SYS_INT_STATUS_REG, 1); 176 // IntStatus 第 0 位表示 ALS 中断,第 1 位表示 PS 中断。 177 178 return IntStatus; // 返回状态 179} 180 181function ap3216c_int_init() { ; } 182 183/** 184 * @brief 配置 中断输入引脚 185 * @param 无 186 * @retval 无 187 */ 188function ap3216c_int_Config() { ; } 189 190/** 191 * This function initializes ap3216c registered device driver 192 * 193 * @param no 194 * 195 * @return the ap3216c device. 196 */ 197function init(i2cid) 198{ 199 ap3216cDev = i2c.open({id: i2cid}); 200 fakeSleep(30); 201 202 /* reset ap3216c */ 203 reset_sensor(); 204 fakeSleep(100); 205 ap3216c_set_param(AP3216C_SYSTEM_MODE, AP3216C_MODE_ALS_AND_PS); 206 fakeSleep(150); // delay at least 112.5ms 207 208 ap3216c_int_Config(); 209 ap3216c_int_init(); 210} 211 212function ap3216c_deinit() { 213 ap3216cDev.close(); 214} 215 216/** 217 * This function reads light by ap3216c sensor measurement 218 * 219 * @param no 220 * 221 * @return the ambient light converted to float data. 222 */ 223function ap3216c_read_ambient_light() 224{ 225 var brightness; // default error data 226 var read_data; 227 var range; 228 229 read_data = read_low_and_high(AP3216C_ALS_DATA_L_REG, 1); 230 range = ap3216c_get_param(AP3216C_ALS_RANGE); 231 //console.log("ap3216c_read_ambient_light read_data is " , read_data, range); 232 if (range == AP3216C_ALS_RANGE_20661) { 233 brightness = 234 0.35 * read_data; // sensor ambient light converse to reality 235 } else if (range == AP3216C_ALS_RANGE_5162) { 236 brightness = 237 0.0788 * read_data; // sensor ambient light converse to reality 238 } else if (range == AP3216C_ALS_RANGE_1291) { 239 brightness = 240 0.0197 * read_data; // sensor ambient light converse to reality 241 } else if (range == AP3216C_ALS_RANGE_323) { 242 brightness = 243 0.0049 * read_data; // sensor ambient light converse to reality 244 } 245 return brightness; 246} 247 248/** 249 * This function reads proximity by ap3216c sensor measurement 250 * 251 * @param no 252 * 253 * @return the proximity data. 254 */ 255function ap3216c_read_ps_data() 256{ 257 var proximity = 0; 258 259 var read_data; 260 read_data = read_low_and_high(AP3216C_PS_DATA_L_REG, 1); // read two data 261 //console.log("ap3216c_read_ps_data read_data is " , read_data); 262 if (1 == ((read_data >> 6) & 0x01 || (read_data >> 14) & 0x01)) { 263 return proximity = 55555; // 红外过高(IR),PS无效 返回一个 55555 的无效数据 264 } 265 266 proximity = (read_data & 0x000f) + (((read_data >> 8) & 0x3f) << 4); // sensor proximity converse to reality 267 268 proximity = proximity >>> 0 269 270 proximity |= read_data & 0x8000; // 取最高位,0 表示物体远离,1 表示物体靠近 271 272 return proximity; // proximity 后十位是数据位,最高位为状态位 273} 274 275/** 276 * This function reads ir by ap3216c sensor measurement 277 * 278 * @param no 279 * 280 * @return the ir data. 281 */ 282function ap3216c_read_ir_data() 283{ 284 var proximity = 0; 285 286 var read_data; 287 read_data = read_low_and_high(AP3216C_IR_DATA_L_REG, 1); // read two data 288 //console.log("ap3216c_read_ir_data read_data is" , read_data); 289 proximity = 290 (read_data & 0x0003) + 291 ((read_data >> 8) & 0xFF); // sensor proximity converse to reality 292 293 proximity = proximity >>> 0 294 295 return proximity; 296} 297 298/** 299 * This function sets parameter of ap3216c sensor 300 * 301 * @param cmd the parameter cmd of device 302 * @param value for setting value in cmd register 303 * 304 * @return the setting parameter status,RT_EOK reprensents setting successfully. 305 */ 306function ap3216c_set_param(cmd, value) 307{ 308 switch (cmd) { 309 case AP3216C_SYSTEM_MODE: 310 { 311 /* default 000,power down */ 312 write_reg(AP3216C_SYS_CONFIGURATION_REG, value); 313 break; 314 } 315 case AP3216C_INT_PARAM: 316 { 317 write_reg(AP3216C_SYS_INT_CLEAR_MANNER_REG, value); 318 319 break; 320 } 321 322 case AP3216C_ALS_RANGE: 323 { 324 var args = read_regs(AP3216C_ALS_CONFIGURATION_REG, 1); 325 args &= 0xcf; 326 args |= value << 4; 327 write_reg(AP3216C_ALS_CONFIGURATION_REG, args); 328 329 break; 330 } 331 case AP3216C_ALS_PERSIST: 332 { 333 var args = read_regs(AP3216C_ALS_CONFIGURATION_REG, 1); 334 args &= 0xf0; 335 args |= value; 336 write_reg(AP3216C_ALS_CONFIGURATION_REG, args); 337 338 break; 339 } 340 case AP3216C_ALS_LOW_THRESHOLD_L: 341 { 342 write_reg(AP3216C_ALS_THRESHOLD_LOW_L_REG, value); 343 344 break; 345 } 346 case AP3216C_ALS_LOW_THRESHOLD_H: 347 { 348 write_reg(AP3216C_ALS_THRESHOLD_LOW_H_REG, value); 349 350 break; 351 } 352 case AP3216C_ALS_HIGH_THRESHOLD_L: 353 { 354 write_reg(AP3216C_ALS_THRESHOLD_HIGH_L_REG, value); 355 356 break; 357 } 358 case AP3216C_ALS_HIGH_THRESHOLD_H: 359 { 360 write_reg(AP3216C_ALS_THRESHOLD_HIGH_H_REG, value); 361 362 break; 363 } 364 case AP3216C_PS_GAIN: 365 { 366 var args = read_regs(AP3216C_PS_CONFIGURATION_REG, 1); 367 args &= 0xf3; 368 args |= value; 369 write_reg(AP3216C_PS_CONFIGURATION_REG, args); 370 371 break; 372 } 373 case AP3216C_PS_PERSIST: 374 { 375 var args = read_regs(AP3216C_PS_CONFIGURATION_REG, 1); 376 args &= 0xfc; 377 args |= value; 378 write_reg(AP3216C_PS_CONFIGURATION_REG, args); 379 380 break; 381 } 382 case AP3216C_PS_LOW_THRESHOLD_L: 383 { 384 write_reg(AP3216C_PS_THRESHOLD_LOW_L_REG, value); 385 386 break; 387 } 388 case AP3216C_PS_LOW_THRESHOLD_H: 389 { 390 write_reg(AP3216C_PS_THRESHOLD_LOW_H_REG, value); 391 392 break; 393 } 394 case AP3216C_PS_HIGH_THRESHOLD_L: 395 { 396 write_reg(AP3216C_PS_THRESHOLD_HIGH_L_REG, value); 397 398 break; 399 } 400 case AP3216C_PS_HIGH_THRESHOLD_H: 401 { 402 write_reg(AP3216C_PS_THRESHOLD_HIGH_H_REG, value); 403 404 break; 405 } 406 407 default: 408 { 409 } 410 } 411} 412 413/** 414 * This function gets parameter of ap3216c sensor 415 * 416 * @param cmd the parameter cmd of device 417 * @param value to get value in cmd register 418 * 419 * @return the getting parameter status,RT_EOK reprensents getting successfully. 420 */ 421function ap3216c_get_param(cmd) 422{ 423 switch (cmd) { 424 case AP3216C_SYSTEM_MODE: 425 { 426 value = read_regs(AP3216C_SYS_CONFIGURATION_REG, 1); 427 428 break; 429 } 430 case AP3216C_INT_PARAM: 431 { 432 value = read_regs(AP3216C_SYS_INT_CLEAR_MANNER_REG, 1); 433 434 break; 435 } 436 case AP3216C_ALS_RANGE: 437 { 438 var value = read_regs(AP3216C_ALS_CONFIGURATION_REG, 1); 439 temp = (value & 0xff) >> 4; 440 441 value = temp; 442 443 break; 444 } 445 case AP3216C_ALS_PERSIST: 446 { 447 var temp = read_regs(AP3216C_ALS_CONFIGURATION_REG, 1); 448 temp = value & 0x0f; 449 450 value = temp; 451 452 break; 453 } 454 case AP3216C_ALS_LOW_THRESHOLD_L: 455 { 456 value = read_regs(AP3216C_ALS_THRESHOLD_LOW_L_REG, 1); 457 458 break; 459 } 460 case AP3216C_ALS_LOW_THRESHOLD_H: 461 { 462 value = read_regs(AP3216C_ALS_THRESHOLD_LOW_H_REG, 1); 463 464 break; 465 } 466 case AP3216C_ALS_HIGH_THRESHOLD_L: 467 { 468 value = read_regs(AP3216C_ALS_THRESHOLD_HIGH_L_REG, 1); 469 470 break; 471 } 472 case AP3216C_ALS_HIGH_THRESHOLD_H: 473 { 474 value = read_regs(AP3216C_ALS_THRESHOLD_HIGH_H_REG, 1); 475 476 break; 477 } 478 case AP3216C_PS_GAIN: 479 { 480 var temp = read_regs(AP3216C_PS_CONFIGURATION_REG, 1); 481 482 value = (temp & 0xc) >> 2; 483 484 break; 485 } 486 case AP3216C_PS_PERSIST: 487 { 488 var temp = read_regs(AP3216C_PS_CONFIGURATION_REG, 1); 489 490 value = temp & 0x3; 491 492 break; 493 } 494 case AP3216C_PS_LOW_THRESHOLD_L: 495 { 496 value = read_regs(AP3216C_PS_THRESHOLD_LOW_L_REG, 1); 497 498 break; 499 } 500 case AP3216C_PS_LOW_THRESHOLD_H: 501 { 502 value = read_regs(AP3216C_PS_THRESHOLD_LOW_H_REG, 1); 503 break; 504 } 505 case AP3216C_PS_HIGH_THRESHOLD_L: 506 { 507 value = read_regs(AP3216C_PS_THRESHOLD_HIGH_L_REG, 1); 508 509 break; 510 } 511 case AP3216C_PS_HIGH_THRESHOLD_H: 512 { 513 value = read_regs(AP3216C_PS_THRESHOLD_HIGH_H_REG, 1); 514 515 break; 516 } 517 518 default: 519 { 520 } 521 } 522 return value; 523} 524 525 // 初始化MPU6050 526// 返回值:0,成功 527// 其他,错误代码 528function init(i2cid) { 529 530 ap3216cDev = i2c.open({id: i2cid}); 531 fakeSleep(100); 532 533 /* reset ap3216c */ 534 reset_sensor(); 535 fakeSleep(100); 536 ap3216c_set_param(AP3216C_SYSTEM_MODE, AP3216C_MODE_ALS_AND_PS); 537 fakeSleep(150); // delay at least 112.5ms 538 539 ap3216c_int_Config(); 540 ap3216c_int_init(); 541 542} 543 544// De-init qlc5883 545function deinit() { 546 ap3216cDev.close(); 547} 548 549module.exports = { 550 init, 551 deinit, 552 ap3216c_read_ambient_light, 553 ap3216c_read_ps_data, 554 ap3216c_read_ir_data, 555 deinit, 556}