1""" 2Copyright (C) 2015-2020 Alibaba Group Holding Limited 3 4The driver for AP3216C chip, The AP3216C is an integrated ALS & PS module 5that includes a digital ambient light sensor [ALS], a proximity sensor [PS], 6and an IR LED in a single package. 7""" 8from micropython import const 9from driver import I2C 10from utime import sleep_ms 11import math 12 13AP3216C_ADDR = const(0x1e) 14 15# System Register 16AP3216C_SYS_CONFIGURATION_REG = const(0x00) 17AP3216C_SYS_INT_STATUS_REG = const(0x01) 18AP3216C_SYS_INT_CLEAR_MANNER_REG = const(0x02) 19AP3216C_IR_DATA_L_REG = const(0x0A) 20AP3216C_IR_DATA_H_REG = const(0x0B) 21AP3216C_ALS_DATA_L_REG = const(0x0C) 22AP3216C_ALS_DATA_H_REG = const(0x0D) 23AP3216C_PS_DATA_L_REG = const(0x0E) 24AP3216C_PS_DATA_H_REG = const(0x0F) 25 26# ALS Register 27AP3216C_ALS_CONFIGURATION_REG = const(0x10) 28AP3216C_ALS_CALIBRATION_REG = const(0x19) 29AP3216C_ALS_THRESHOLD_LOW_L_REG = const(0x1A) 30AP3216C_ALS_THRESHOLD_LOW_H_REG = const(0x1B) 31AP3216C_ALS_THRESHOLD_HIGH_L_REG = const(0x1C) 32AP3216C_ALS_THRESHOLD_HIGH_H_REG = const(0x1D) 33 34# PS Register 35AP3216C_PS_CONFIGURATION_REG = const(0x20) 36AP3216C_PS_LED_DRIVER_REG = const(0x21) 37AP3216C_PS_INT_FORM_REG = const(0x22) 38AP3216C_PS_MEAN_TIME_REG = const(0x23) 39AP3216C_PS_LED_WAITING_TIME_REG = const(0x24) 40AP3216C_PS_CALIBRATION_L_REG = const(0x28) 41AP3216C_PS_CALIBRATION_H_REG = const(0x29) 42AP3216C_PS_THRESHOLD_LOW_L_REG = const(0x2A) 43AP3216C_PS_THRESHOLD_LOW_H_REG = const(0x2B) 44AP3216C_PS_THRESHOLD_HIGH_L_REG = const(0x2C) 45AP3216C_PS_THRESHOLD_HIGH_H_REG = const(0x2D) 46 47#mode value 48AP3216C_MODE_POWER_DOWN = const(0x0) 49AP3216C_MODE_ALS = const(0x1) 50AP3216C_MODE_PS = const(0x2) 51AP3216C_MODE_ALS_AND_PS = const(0x3) 52AP3216C_MODE_SW_RESET = const(0x4) 53AP3216C_MODE_ALS_ONCE = const(0x5) 54AP3216C_MODE_PS_ONCE = const(0x6) 55AP3216C_MODE_ALS_AND_PS_ONCE = const(0x7) 56 57#ap3216c_int_clear_manner 58AP3216C_INT_CLEAR_MANNER_BY_READING = const(0x0) 59AP3216C_ALS_CLEAR_MANNER_BY_SOFTWARE = const(0x1) 60 61#als_range 62AP3216C_ALS_RANGE_20661 = const(0x0) 63AP3216C_ALS_RANGE_5162 = const(0x1) 64AP3216C_ALS_RANGE_1291 = const(0x2) 65AP3216C_ALS_RANGE_323 = const(0x3) 66 67#als_range 68AP3216C_PS_GAIN1 = const(0x0) 69AP3216C_PS_GAIN2 = const(0x1) 70AP3216C_PS_GAIN4 = const(0x2) 71AP3216C_PS_GAIN8 = const(0x3) 72 73AP3216C_SYSTEM_MODE = const(0x0) 74AP3216C_INT_PARAM = const(0x1) 75AP3216C_ALS_RANGE = const(0x2) 76AP3216C_ALS_PERSIST = const(0x3) 77AP3216C_ALS_CALIBRATION = const(0x4) 78AP3216C_ALS_LOW_THRESHOLD_L = const(0x5) 79AP3216C_ALS_LOW_THRESHOLD_H = const(0x6) 80AP3216C_ALS_HIGH_THRESHOLD_L = const(0x7) 81AP3216C_ALS_HIGH_THRESHOLD_H = const(0x8) 82AP3216C_PS_INTEGRATED_TIME = const(0x9) 83AP3216C_PS_GAIN = const(0xa) 84AP3216C_PS_PERSIST = const(0xb) 85AP3216C_PS_LED_CONTROL = const(0xc) 86AP3216C_PS_LED_DRIVER_RATIO = const(0xd) 87AP3216C_PS_INT_MODE = const(0xe) 88AP3216C_PS_MEAN_TIME = const(0xf) 89AP3216C_PS_WAITING_TIME = const(0x10) 90AP3216C_PS_CALIBRATION_L = const(0x11) 91AP3216C_PS_CALIBRATION_H = const(0x12) 92AP3216C_PS_LOW_THRESHOLD_L = const(0x13) 93AP3216C_PS_LOW_THRESHOLD_H = const(0x14) 94AP3216C_PS_HIGH_THRESHOLD_L = const(0x15) 95AP3216C_PS_HIGH_THRESHOLD_H = const(0x16) 96 97class AP3216CError(Exception): 98 def __init__(self, value=0, msg="ap3216c common error"): 99 self.value = value 100 self.msg = msg 101 102 def __str__(self): 103 return "Error code:%d, Error message: %s" % (self.value, str(self.msg)) 104 105 __repr__ = __str__ 106 107class AP3216C(object): 108 """ 109 This class implements ap3216c chip's defs. 110 """ 111 def __init__(self): 112 self.i2cDev = None 113 114 def open(self, devid): 115 self.i2cDev = I2C() 116 self.i2cDev.open(devid) 117 118# 写寄存器的值 119 def write_reg(self, addr, data): 120 msgbuf = bytearray([data]) 121 self.i2cDev.writeReg(addr, msgbuf) 122 print("--> write addr " + str(addr) + ", value = " + str(msgbuf)) 123 124# 读寄存器的值 125 def read_regs(self, addr, len): 126 buf = bytearray(len) 127 self.i2cDev.readReg(addr, buf) 128 print("--> read " + str(len) + " bytes from addr " + str(addr) + ", " + str(len) + " bytes value = " + str(buf)) 129 return buf; 130 131 # 软件复位传感器 132 def reset_sensor(self): 133 self.write_reg(AP3216C_SYS_CONFIGURATION_REG, AP3216C_MODE_SW_RESET); # reset 134 135 def read_low_and_high(self, reg, len): 136 # buf 137 138 # buf[0] = self.read_regs(reg, len) # 读低字节 139 # buf[1] = self.read_regs(reg + 1, len) # 读高字节 140 data = self.read_regs(reg, len)[0] | (self.read_regs(reg + 1, len)[0] << len * 8) # 合并数据 141 142 if (data > (1 << 15)): 143 data = data - (1<<16) 144 145 return data 146 147 def ap3216c_get_IntStatus(self): 148 # 读中断状态寄存器 149 IntStatus = self.read_regs(AP3216C_SYS_INT_STATUS_REG, 1)[0] 150 # IntStatus 第 0 位表示 ALS 中断,第 1 位表示 PS 中断。 151 return IntStatus # 返回状态 152 153 def ap3216c_int_init(self): 154 print("ap3216c_int_init") 155 #配置 中断输入引脚 156 def ap3216c_int_Config(self): 157 print("ap3216c_int_Config") 158 159 #初始化入口 160 def init(self): 161 # reset ap3216c 162 self.reset_sensor() 163 sleep_ms(100) 164 self.ap3216c_set_param(AP3216C_SYSTEM_MODE, AP3216C_MODE_ALS_AND_PS) 165 sleep_ms(150) # delay at least 112.5ms 166 167 self.ap3216c_int_Config() 168 self.ap3216c_int_init() 169 170 171 # This function reads light by ap3216c sensor measurement 172 # @param no 173 # @return the ambient light converted to float data. 174 # 175 def ap3216c_read_ambient_light(self): 176 read_data = self.read_low_and_high(AP3216C_ALS_DATA_L_REG, 1) 177 range = self.ap3216c_get_param(AP3216C_ALS_RANGE) 178 print("ap3216c_read_ambient_light read_data is " , read_data, range) 179 if (range == AP3216C_ALS_RANGE_20661): 180 brightness = 0.35 * read_data # sensor ambient light converse to reality 181 elif (range == AP3216C_ALS_RANGE_5162): 182 brightness = 0.0788 * read_data # sensor ambient light converse to reality 183 elif (range == AP3216C_ALS_RANGE_1291): 184 brightness = 0.0197 * read_data # sensor ambient light converse to reality 185 elif (range == AP3216C_ALS_RANGE_323): 186 brightness = 0.0049 * read_data # sensor ambient light converse to reality 187 188 return brightness 189 190 #This function reads proximity by ap3216c sensor measurement 191 #@param no 192 #@return the proximity data. 193 def ap3216c_read_ps_data(self): 194 read_data = self.read_low_and_high(AP3216C_PS_DATA_L_REG, 1) # read two data 195 print("ap3216c_read_ps_data read_data is " , read_data); 196 if (1 == ((read_data >> 6) & 0x01 or (read_data >> 14) & 0x01)) : 197 return 55555 # 红外过高(IR),PS无效 返回一个 55555 的无效数据 198 199 proximity = (read_data & 0x000f) + (((read_data >> 8) & 0x3f) << 4) 200 # sensor proximity converse to reality 201 if (proximity > (1 << 15)) : 202 proximity = proximity - (1<<16) 203 204 proximity |= read_data & 0x8000 # 取最高位,0 表示物体远离,1 表示物体靠近 205 return proximity # proximity 后十位是数据位,最高位为状态位 206 207 208 #This function reads ir by ap3216c sensor measurement 209 #@param no 210 #@return the ir data. 211 def ap3216c_read_ir_data(self): 212 read_data = self.read_low_and_high(AP3216C_IR_DATA_L_REG, 1) # read two data 213 print("ap3216c_read_ir_data read_data is" , read_data); 214 proximity = (read_data & 0x0003) + ((read_data >> 8) & 0xFF) 215 # sensor proximity converse to reality 216 if (proximity > (1 << 15)) : 217 proximity = proximity - (1<<16) 218 219 return proximity 220 221 #This function sets parameter of ap3216c sensor 222 #@param cmd the parameter cmd of device 223 #@param value for setting value in cmd register 224 #@return the setting parameter status,RT_EOK reprensents setting successfully. 225 226 def ap3216c_set_param(self, cmd, value): 227 if cmd == AP3216C_SYSTEM_MODE: 228 # default 000,power down 229 self.write_reg(AP3216C_SYS_CONFIGURATION_REG, value) 230 elif cmd == AP3216C_INT_PARAM: 231 self.write_reg(AP3216C_SYS_INT_CLEAR_MANNER_REG, value) 232 elif cmd == AP3216C_ALS_RANGE: 233 args = self.read_regs(AP3216C_ALS_CONFIGURATION_REG, 1)[0] 234 args &= 0xcf 235 args |= value << 4 236 self.write_reg(AP3216C_ALS_CONFIGURATION_REG, args) 237 elif cmd == AP3216C_ALS_PERSIST: 238 args = self.read_regs(AP3216C_ALS_CONFIGURATION_REG, 1)[0] 239 args &= 0xf0 240 args |= value 241 self.write_reg(AP3216C_ALS_CONFIGURATION_REG, args) 242 elif cmd == AP3216C_ALS_LOW_THRESHOLD_L: 243 self.write_reg(AP3216C_ALS_THRESHOLD_LOW_L_REG, value) 244 elif cmd == AP3216C_ALS_LOW_THRESHOLD_H: 245 self.write_reg(AP3216C_ALS_THRESHOLD_LOW_H_REG, value) 246 elif cmd == AP3216C_ALS_HIGH_THRESHOLD_L: 247 self.write_reg(AP3216C_ALS_THRESHOLD_HIGH_L_REG, value) 248 elif cmd == AP3216C_ALS_HIGH_THRESHOLD_H: 249 self.write_reg(AP3216C_ALS_THRESHOLD_HIGH_H_REG, value) 250 elif cmd == AP3216C_PS_GAIN: 251 args = self.read_regs(AP3216C_PS_CONFIGURATION_REG, 1)[0] 252 args &= 0xf3 253 args |= value 254 self.write_reg(AP3216C_PS_CONFIGURATION_REG, args) 255 elif cmd == AP3216C_PS_PERSIST: 256 args = self.read_regs(AP3216C_PS_CONFIGURATION_REG, 1)[0] 257 args &= 0xfc 258 args |= value 259 self.write_reg(AP3216C_PS_CONFIGURATION_REG, args) 260 elif cmd == AP3216C_PS_LOW_THRESHOLD_L: 261 self.write_reg(AP3216C_PS_THRESHOLD_LOW_L_REG, value) 262 elif cmd == AP3216C_PS_LOW_THRESHOLD_H: 263 self.write_reg(AP3216C_PS_THRESHOLD_LOW_H_REG, value) 264 elif cmd == AP3216C_PS_HIGH_THRESHOLD_L: 265 self.write_reg(AP3216C_PS_THRESHOLD_HIGH_L_REG, value) 266 elif cmd == AP3216C_PS_HIGH_THRESHOLD_H: 267 self.write_reg(AP3216C_PS_THRESHOLD_HIGH_H_REG, value) 268 269 #This function gets parameter of ap3216c sensor 270 #@param cmd the parameter cmd of device 271 #@param value to get value in cmd register 272 #@return the getting parameter status,RT_EOK reprensents getting successfully. 273 def ap3216c_get_param(self, cmd): 274 if cmd == AP3216C_SYSTEM_MODE: 275 value = self.read_regs(AP3216C_SYS_CONFIGURATION_REG, 1)[0] 276 elif cmd == AP3216C_INT_PARAM: 277 value = self.read_regs(AP3216C_SYS_INT_CLEAR_MANNER_REG, 1)[0] 278 elif cmd == AP3216C_ALS_RANGE: 279 value = self.read_regs(AP3216C_ALS_CONFIGURATION_REG, 1)[0] 280 temp = (value & 0xff) >> 4 281 value = temp 282 elif cmd == AP3216C_ALS_PERSIST: 283 temp = self.read_regs(AP3216C_ALS_CONFIGURATION_REG, 1)[0] 284 temp = value & 0x0f 285 value = temp 286 elif cmd == AP3216C_ALS_LOW_THRESHOLD_L: 287 value = self.read_regs(AP3216C_ALS_THRESHOLD_LOW_L_REG, 1)[0] 288 elif cmd == AP3216C_ALS_LOW_THRESHOLD_H: 289 value = self.read_regs(AP3216C_ALS_THRESHOLD_LOW_H_REG, 1)[0] 290 elif cmd == AP3216C_ALS_HIGH_THRESHOLD_L: 291 value = self.read_regs(AP3216C_ALS_THRESHOLD_HIGH_L_REG, 1)[0] 292 elif cmd == AP3216C_ALS_HIGH_THRESHOLD_H: 293 value = self.read_regs(AP3216C_ALS_THRESHOLD_HIGH_H_REG, 1)[0] 294 elif cmd == AP3216C_PS_GAIN: 295 temp = self.read_regs(AP3216C_PS_CONFIGURATION_REG, 1)[0] 296 value = (temp & 0xc) >> 2 297 elif cmd == AP3216C_PS_PERSIST: 298 temp = self.read_regs(AP3216C_PS_CONFIGURATION_REG, 1)[0] 299 value = temp & 0x3 300 elif cmd == AP3216C_PS_LOW_THRESHOLD_L: 301 value = self.read_regs(AP3216C_PS_THRESHOLD_LOW_L_REG, 1)[0] 302 elif cmd == AP3216C_PS_LOW_THRESHOLD_H: 303 value = self.read_regs(AP3216C_PS_THRESHOLD_LOW_H_REG, 1)[0] 304 elif cmd == AP3216C_PS_HIGH_THRESHOLD_L: 305 value = self.read_regs(AP3216C_PS_THRESHOLD_HIGH_L_REG, 1)[0] 306 elif cmd == AP3216C_PS_HIGH_THRESHOLD_H: 307 value = self.read_regs(AP3216C_PS_THRESHOLD_HIGH_H_REG, 1)[0] 308 309 return value 310 311 def close(self): 312 self.i2cDev.close() 313