1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "aos/kernel.h"
5 #include "sensor_drv_api.h"
6 #include "sensor_hal.h"
7
8
9 /*******************************************************************************
10 ********************************* MACROS **********************************
11 ******************************************************************************/
12 #define LTR381_ADDR_TRANS(n) ((n) << 1)
13 #define LTR381_GET_BITSLICE(uint8Val, bitName) (((uint8Val) & (LTR381_##bitName##__MSK)) >> (LTR381_##bitName##__POS))
14 #define LTR381_SET_BITSLICE(uint8Val, bitName, bitVal) (((uint8Val) & ~(LTR381_##bitName##__MSK)) | ((bitVal << (LTR381_##bitName##__POS)) & (LTR381_##bitName##__MSK)))
15
16 /*******************************************************************************
17 ************************** SENSOR SPECIFICATIONS **************************
18 ******************************************************************************/
19 /* I2C device address */
20 #define LTR381_SLAVE_ADDR (0x53)
21 #define LTR381_I2C_ADDR LTR381_ADDR_TRANS(LTR381_SLAVE_ADDR)
22
23 /* Device info */
24 #define LTR381_PART_ID_VAL 0xC2
25 #define LTR381_MANUFAC_ID_VAL 0x05
26
27 #define LTR381_WAIT_TIME_PER_CHECK (10)
28 #define LTR381_WAIT_TIME_TOTAL (100)
29
30 /*******************************************************************************
31 ************* Non-Configurable (Unless data sheet is updated) *************
32 ******************************************************************************/
33 /* Device register set address */
34 #define LTR381_MAIN_CTRL_REG (0x00)
35 #define LTR381_ALS_CS_MEAS_RATE_REG (0x04)
36 #define LTR381_ALS_CS_GAIN_REG (0x05)
37 #define LTR381_PART_ID_REG (0x06)
38 #define LTR381_MAIN_STATUS_REG (0x07)
39 #define LTR381_CS_DATA_IR_0_REG (0x0A)
40 #define LTR381_CS_DATA_IR_1_REG (0x0B)
41 #define LTR381_CS_DATA_IR_2_REG (0x0C)
42 #define LTR381_CS_DATA_GREEN_0_REG (0x0D)
43 #define LTR381_CS_DATA_GREEN_1_REG (0x0E)
44 #define LTR381_CS_DATA_GREEN_2_REG (0x0F)
45 #define LTR381_CS_DATA_RED_0_REG (0x10)
46 #define LTR381_CS_DATA_RED_1_REG (0x11)
47 #define LTR381_CS_DATA_RED_2_REG (0x12)
48 #define LTR381_CS_DATA_BLUE_0_REG (0x13)
49 #define LTR381_CS_DATA_BLUE_1_REG (0x14)
50 #define LTR381_CS_DATA_BLUE_2_REG (0x15)
51 #define LTR381_INT_CFG_REG (0x19)
52 #define LTR381_INT_PST_REG (0x1A)
53 #define LTR381_ALS_THRES_UP_0_REG (0x21)
54 #define LTR381_ALS_THRES_UP_1_REG (0x22)
55 #define LTR381_ALS_THRES_UP_2_REG (0x23)
56 #define LTR381_ALS_THRES_LOW_0_REG (0x24)
57 #define LTR381_ALS_THRES_LOW_1_REG (0x25)
58 #define LTR381_ALS_THRES_LOW_2_REG (0x26)
59
60 /* Register MAIN_CTRL field */
61 #define LTR381_ALS_CS_ENABLE__REG (LTR381_MAIN_CTRL_REG)
62 #define LTR381_ALS_CS_ENABLE__POS (1)
63 #define LTR381_ALS_CS_ENABLE__MSK (0x02)
64 #define LTR381_CS_MODE__REG (LTR381_MAIN_CTRL_REG)
65 #define LTR381_CS_MODE__POS (2)
66 #define LTR381_CS_MODE__MSK (4)
67 #define LTR381_SW_RESET__REG (LTR381_MAIN_CTRL_REG)
68 #define LTR381_SW_RESET__POS (4)
69 #define LTR381_SW_RESET__MSK (0x10)
70
71 /* Register ALS_CS_MEAS_RATE field */
72 #define LTR381_ALS_CS_MEAS_RATE__REG (LTR381_ALS_CS_MEAS_RATE_REG)
73 #define LTR381_ALS_CS_MEAS_RATE__POS (0)
74 #define LTR381_ALS_CS_MEAS_RATE__MSK (0x07)
75 #define LTR381_ALS_CS_RESOLUTION__REG (LTR381_ALS_CS_MEAS_RATE_REG)
76 #define LTR381_ALS_CS_RESOLUTION__POS (4)
77 #define LTR381_ALS_CS_RESOLUTION__MSK (0x70)
78
79 /* Register ALS_CS_GAIN field */
80 #define LTR381_ALS_CS_GAIN_RANGE__REG (LTR381_ALS_CS_GAIN_REG)
81 #define LTR381_ALS_CS_GAIN_RANGE__POS (0)
82 #define LTR381_ALS_CS_GAIN_RANGE__MSK (0x07)
83
84 /* Register PART_ID field */
85 #define LTR381_PART_NUMBER_ID__REG (LTR381_PART_ID_REG)
86 #define LTR381_PART_NUMBER_ID__POS (4)
87 #define LTR381_PART_NUMBER_ID__MSK (0xF0)
88
89 /* Register MAIN_STATUS field */
90 #define LTR381_ALS_CS_DATA_STATUS__REG (LTR381_MAIN_STATUS_REG)
91 #define LTR381_ALS_CS_DATA_STATUS__POS (3)
92 #define LTR381_ALS_CS_DATA_STATUS__MSK (0x08)
93 #define LTR381_ALS_CS_INT_STATUS__REG (LTR381_MAIN_STATUS_REG)
94 #define LTR381_ALS_CS_INT_STATUS__POS (4)
95 #define LTR381_ALS_CS_INT_STATUS__MSK (0x10)
96 #define LTR381_POWER_ON_STATUS__REG (LTR381_MAIN_STATUS_REG)
97 #define LTR381_POWER_ON_STATUS__POS (5)
98 #define LTR381_POWER_ON_STATUS__MSK (0x20)
99
100 /* Register INT_CFG field */
101 #define LTR381_ALS_INT_PIN_EN__REG (LTR381_INT_CFG_REG)
102 #define LTR381_ALS_INT_PIN_EN__POS (2)
103 #define LTR381_ALS_INT_PIN_EN__MSK (0x04)
104 #define LTR381_ALS_INT_SEL__REG (LTR381_INT_CFG_REG)
105 #define LTR381_ALS_INT_SEL__POS (4)
106 #define LTR381_ALS_INT_SEL__MSK (0x30)
107
108 /* Register INT_PST field */
109 #define LTR381_ALS_CS_PERSIST__REG (LTR381_INT_PST_REG)
110 #define LTR381_ALS_CS_PERSIST__POS (4)
111 #define LTR381_ALS_CS_PERSIST__MSK (0xF0)
112
113 /* Field value enumeration */
114 typedef enum {
115 LTR381_ALS_STANDBY_MODE = 0x00,
116 LTR381_ALS_ACTIVE_MODE = 0x01,
117 } LTR381_ALS_CS_ENABLE_VAL;
118
119 typedef enum {
120 LTR381_ALS_MODE = 0x00,
121 LTR381_CS_MODE = 0x01,
122 } LTR381_ALS_CS_MODE_VAL;
123
124 typedef enum {
125 LTR381_ALS_NO_RESET = 0x00,
126 LTR381_ALS_RESET = 0x01,
127 } LTR381_SW_RESET_VAL;
128
129 typedef enum {
130 LTR381_ALS_CS_MEAS_RATE_25MS = 0x00,
131 LTR381_ALS_CS_MEAS_RATE_50MS = 0x01,
132 LTR381_ALS_CS_MEAS_RATE_100MS = 0x02,
133 LTR381_ALS_CS_MEAS_RATE_200MS = 0x03,
134 LTR381_ALS_CS_MEAS_RATE_500MS = 0x04,
135 LTR381_ALS_CS_MEAS_RATE_1000MS = 0x05,
136 LTR381_ALS_CS_MEAS_RATE_2000MS = 0x06,
137 } LTR381_ALS_CS_MEAS_RATE_VAL;
138
139 typedef enum {
140 LTR381_ALS_CS_RESOLUTION_20BIT = 0x00,
141 LTR381_ALS_CS_RESOLUTION_19BIT = 0x01,
142 LTR381_ALS_CS_RESOLUTION_18BIT = 0x02,
143 LTR381_ALS_CS_RESOLUTION_17BIT = 0x03,
144 LTR381_ALS_CS_RESOLUTION_16BIT = 0x04,
145 } LTR381_ALS_CS_RESOLUTION_VAL;
146
147 typedef enum {
148 LTR381_ALS_CS_GAIN_RANGE_1 = 0x00,
149 LTR381_ALS_CS_GAIN_RANGE_3 = 0x01,
150 LTR381_ALS_CS_GAIN_RANGE_6 = 0x02,
151 LTR381_ALS_CS_GAIN_RANGE_9 = 0x03,
152 LTR381_ALS_CS_GAIN_RANGE_18 = 0x04,
153 } LTR381_ALS_CS_GAIN_RANGE_VAL;
154
155 typedef enum {
156 LTR381_CS_ALS_DATA_OLD = 0x00,
157 LTR381_CS_ALS_DATA_NEW = 0x01,
158 } LTR381_CS_ALS_DATA_STATUS_VAL;
159
160 typedef enum {
161 LTR381_CS_ALS_INT_FALSE = 0x00,
162 LTR381_CS_ALS_INT_TRUE = 0x01,
163 } LTR381_CS_ALS_INT_STATUS_VAL;
164
165 typedef enum {
166 LTR381_POWER_ON_NORMAL = 0x00,
167 LTR381_POWER_ON_GOING = 0x01,
168 } LTR381_POWER_ON_STATUS_VAL;
169
170 typedef enum {
171 LTR381_ALS_INT_INACTIVE = 0x00,
172 LTR381_ALS_INT_ACTIVE = 0x01,
173 } LTR381_ALS_INT_PIN_EN_VAL;
174
175 typedef enum {
176 LTR381_ALS_INT_IR_CHANNEL = 0x00,
177 LTR381_ALS_INT_GREEN_CHANNEL = 0x01,
178 LTR381_ALS_INT_BLUE_CHANNEL = 0x02,
179 LTR381_ALS_INT_RED_CHANNEL = 0x03,
180 } LTR381_ALS_INT_SELECT_VAL;
181
182
183 i2c_dev_t ltr381_ctx = {
184 .port = 3,
185 .config.address_width = 8,
186 .config.freq = 100000,
187 .config.dev_addr = LTR381_I2C_ADDR,
188 };
189
190 static uint8_t g_init_bitwise = 0;
191
192
drv_rgb_liteon_ltr381_validate_id(i2c_dev_t * drv,uint8_t part_id)193 static int drv_rgb_liteon_ltr381_validate_id(i2c_dev_t* drv, uint8_t part_id)
194 {
195 int ret = 0;
196 uint8_t part_id_value = 0;
197
198 if (drv == NULL) {
199 return -1;
200 }
201
202 ret = sensor_i2c_read(drv, LTR381_PART_ID_REG, &part_id_value, I2C_DATA_LEN, I2C_OP_RETRIES);
203 if (unlikely(ret)) {
204 return ret;
205 }
206
207 if (part_id_value != part_id) {
208 return -1;
209 }
210
211 return 0;
212 }
213
drv_rgb_liteon_ltr381_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)214 static int drv_rgb_liteon_ltr381_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
215 {
216 int ret = 0;
217 uint8_t dev_mode = 0;
218 uint8_t value = 0;
219
220 ret = sensor_i2c_read(drv, LTR381_MAIN_CTRL_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
221 if (unlikely(ret)) {
222 return ret;
223 }
224
225 switch (mode) {
226 case DEV_POWER_OFF:
227 case DEV_SLEEP:
228 dev_mode = LTR381_SET_BITSLICE(value, ALS_CS_ENABLE, LTR381_ALS_STANDBY_MODE);
229 break;
230 case DEV_POWER_ON:
231 dev_mode = LTR381_SET_BITSLICE(value, ALS_CS_ENABLE, LTR381_ALS_ACTIVE_MODE);
232 break;
233 default:
234 return -1;
235 }
236
237 ret = sensor_i2c_write(drv, LTR381_MAIN_CTRL_REG, &dev_mode, I2C_DATA_LEN, I2C_OP_RETRIES);
238 if (unlikely(ret)) {
239 return ret;
240 }
241
242 return 0;
243 }
244
drv_rgb_liteon_ltr381_is_ready(i2c_dev_t * drv)245 UNUSED static int drv_rgb_liteon_ltr381_is_ready(i2c_dev_t* drv)
246 {
247 int ret = 0;
248 uint8_t value = 0;
249
250 ret = sensor_i2c_read(drv, LTR381_MAIN_STATUS_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
251 if (unlikely(ret)) {
252 return 0;
253 }
254
255 ret = (LTR381_GET_BITSLICE(value, ALS_CS_DATA_STATUS) == LTR381_CS_ALS_DATA_NEW) ? 1 : 0;
256
257 return ret;
258 }
259
drv_rgb_liteon_ltr381_set_default_config(i2c_dev_t * drv)260 static int drv_rgb_liteon_ltr381_set_default_config(i2c_dev_t* drv)
261 {
262 int ret = 0;
263 uint8_t value = 0;
264
265 value = LTR381_SET_BITSLICE(value, ALS_CS_ENABLE, LTR381_ALS_STANDBY_MODE);
266 value = LTR381_SET_BITSLICE(value, CS_MODE, LTR381_CS_MODE);
267 value = LTR381_SET_BITSLICE(value, SW_RESET, LTR381_ALS_NO_RESET);
268 ret = sensor_i2c_write(drv, LTR381_MAIN_CTRL_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
269 if (unlikely(ret)) {
270 return ret;
271 }
272
273 value = 0;
274 value = LTR381_SET_BITSLICE(value, ALS_CS_MEAS_RATE, LTR381_ALS_CS_MEAS_RATE_100MS);
275 value = LTR381_SET_BITSLICE(value, ALS_CS_RESOLUTION, LTR381_ALS_CS_RESOLUTION_18BIT);
276 ret = sensor_i2c_write(drv, LTR381_ALS_CS_MEAS_RATE_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
277 if (unlikely(ret)) {
278 return ret;
279 }
280
281 value = 0;
282 value = LTR381_SET_BITSLICE(value, ALS_CS_GAIN_RANGE, LTR381_ALS_CS_GAIN_RANGE_3);
283 ret = sensor_i2c_write(drv, LTR381_ALS_CS_GAIN_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
284 if (unlikely(ret)) {
285 return ret;
286 }
287
288 value = 0;
289 value = LTR381_SET_BITSLICE(value, ALS_INT_PIN_EN, LTR381_ALS_INT_INACTIVE);
290 value = LTR381_SET_BITSLICE(value, ALS_INT_SEL, LTR381_ALS_INT_GREEN_CHANNEL);
291 ret = sensor_i2c_write(drv, LTR381_INT_CFG_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
292 if (unlikely(ret)) {
293 return ret;
294 }
295
296 value = 0;
297 ret = sensor_i2c_write(drv, LTR381_INT_PST_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
298 if (unlikely(ret)) {
299 return ret;
300 }
301
302 return 0;
303 }
304
drv_rgb_liteon_ltr381_irq_handle(void)305 static void drv_rgb_liteon_ltr381_irq_handle(void)
306 {
307 /* no handle so far */
308 }
309
drv_rgb_liteon_ltr381_open(void)310 static int drv_rgb_liteon_ltr381_open(void)
311 {
312 int ret = 0;
313
314 ret = drv_rgb_liteon_ltr381_set_power_mode(<r381_ctx, DEV_POWER_ON);
315 if (unlikely(ret)) {
316 return -1;
317 }
318
319 LOG("%s %s successfully \n", SENSOR_STR, __func__);
320 return 0;
321 }
322
drv_rgb_liteon_ltr381_close(void)323 static int drv_rgb_liteon_ltr381_close(void)
324 {
325 int ret = 0;
326
327 ret = drv_rgb_liteon_ltr381_set_power_mode(<r381_ctx, DEV_POWER_OFF);
328 if (unlikely(ret)) {
329 return -1;
330 }
331
332 LOG("%s %s successfully \n", SENSOR_STR, __func__);
333 return 0;
334 }
335
drv_rgb_liteon_ltr381_read(void * buf,size_t len)336 static int drv_rgb_liteon_ltr381_read(void *buf, size_t len)
337 {
338 int ret = 0;
339 size_t size;
340 uint8_t reg_ch_red_data[3] = { 0 };
341 uint8_t reg_ch_green_data[3] = { 0 };
342 uint8_t reg_ch_blue_data[3] = { 0 };
343 uint32_t ch_red_data = 0;
344 uint32_t ch_green_data = 0;
345 uint32_t ch_blue_data = 0;
346 rgb_data_t * pdata = (rgb_data_t *) buf;
347
348 if (buf == NULL){
349 return -1;
350 }
351
352 size = sizeof(rgb_data_t);
353 if (len < size){
354 return -1;
355 }
356
357 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_GREEN_0_REG, ®_ch_green_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
358 if (unlikely(ret)) {
359 return -1;
360 }
361
362 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_GREEN_1_REG, ®_ch_green_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
363 if (unlikely(ret)) {
364 return -1;
365 }
366
367 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_GREEN_2_REG, ®_ch_green_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
368 if (unlikely(ret)) {
369 return -1;
370 }
371
372 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_RED_0_REG, ®_ch_red_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
373 if (unlikely(ret)) {
374 return -1;
375 }
376
377 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_RED_1_REG, ®_ch_red_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
378 if (unlikely(ret)) {
379 return -1;
380 }
381
382 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_RED_2_REG, ®_ch_red_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
383 if (unlikely(ret)) {
384 return -1;
385 }
386
387 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_BLUE_0_REG, ®_ch_blue_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
388 if (unlikely(ret)) {
389 return -1;
390 }
391
392 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_BLUE_1_REG, ®_ch_blue_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
393 if (unlikely(ret)) {
394 return -1;
395 }
396
397 ret = sensor_i2c_read(<r381_ctx, LTR381_CS_DATA_BLUE_2_REG, ®_ch_blue_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
398 if (unlikely(ret)) {
399 return -1;
400 }
401
402 ch_red_data = (((uint32_t) reg_ch_red_data[2] << 16) | ((uint32_t) reg_ch_red_data[1] << 8) | reg_ch_red_data[0]);
403 ch_green_data = (((uint32_t) reg_ch_green_data[2] << 16) | ((uint32_t) reg_ch_green_data[1] << 8) | reg_ch_green_data[0]);
404 ch_blue_data = (((uint32_t) reg_ch_blue_data[2] << 16) | ((uint32_t) reg_ch_blue_data[1] << 8) | reg_ch_blue_data[0]);
405 pdata->data[0] = ch_red_data;
406 pdata->data[1] = ch_green_data;
407 pdata->data[2] = ch_blue_data;
408 pdata->timestamp = aos_now_ms();
409
410 return (int) size;
411 }
412
drv_rgb_liteon_ltr381_write(const void * buf,size_t len)413 static int drv_rgb_liteon_ltr381_write(const void *buf, size_t len)
414 {
415 (void) buf;
416 (void) len;
417
418 return 0;
419 }
420
drv_rgb_liteon_ltr381_ioctl(int cmd,unsigned long arg)421 static int drv_rgb_liteon_ltr381_ioctl(int cmd, unsigned long arg)
422 {
423 int ret = 0;
424
425 switch (cmd) {
426 case SENSOR_IOCTL_SET_POWER: {
427 ret = drv_rgb_liteon_ltr381_set_power_mode(<r381_ctx, arg);
428 if (unlikely(ret)) {
429 return -1;
430 }
431 } break;
432 case SENSOR_IOCTL_GET_INFO: {
433 /* fill the dev info here */
434 dev_sensor_info_t *info = (dev_sensor_info_t *) arg;
435 info->vendor = DEV_SENSOR_VENDOR_LITEON;
436 info->model = "LTR381";
437 info->unit = lux;
438 } break;
439 default:
440 return -1;
441 }
442
443 LOG("%s %s successfully \n", SENSOR_STR, __func__);
444 return 0;
445 }
446
drv_rgb_liteon_ltr381_init(void)447 int drv_rgb_liteon_ltr381_init(void)
448 {
449 int ret = 0;
450 sensor_obj_t sensor_rgb;
451 memset(&sensor_rgb, 0, sizeof(sensor_rgb));
452
453 if (!g_init_bitwise) {
454 ret = drv_rgb_liteon_ltr381_validate_id(<r381_ctx, LTR381_PART_ID_VAL);
455 if (unlikely(ret)) {
456 return -1;
457 }
458 }
459
460 if (!g_init_bitwise) {
461 /* fill the sensor_rgb obj parameters here */
462 sensor_rgb.path = dev_rgb_path;
463 sensor_rgb.tag = TAG_DEV_RGB;
464 sensor_rgb.io_port = I2C_PORT;
465 sensor_rgb.mode = DEV_POLLING;
466 sensor_rgb.power = DEV_POWER_OFF;
467 sensor_rgb.open = drv_rgb_liteon_ltr381_open;
468 sensor_rgb.close = drv_rgb_liteon_ltr381_close;
469 sensor_rgb.read = drv_rgb_liteon_ltr381_read;
470 sensor_rgb.write = drv_rgb_liteon_ltr381_write;
471 sensor_rgb.ioctl = drv_rgb_liteon_ltr381_ioctl;
472 sensor_rgb.irq_handle = drv_rgb_liteon_ltr381_irq_handle;
473
474 ret = sensor_create_obj(&sensor_rgb);
475 if (unlikely(ret)) {
476 return -1;
477 }
478
479 ret = drv_rgb_liteon_ltr381_set_default_config(<r381_ctx);
480 if (unlikely(ret)) {
481 return -1;
482 }
483
484 g_init_bitwise |= 1;
485 }
486
487 LOG("%s %s successfully \n", SENSOR_STR, __func__);
488 return 0;
489 }
490
491 SENSOR_DRV_ADD(drv_rgb_liteon_ltr381_init);
492
493