VEML6070 I2C UV sensor driver
[lpc82x] / extdrv / veml6070_uv_sensor.c
1 /****************************************************************************
2  *   extdrv/veml6070_uv_sensor.c
3  *
4  * VEML6070 I2C UV sensor driver
5  *
6  * Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
7  *
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  *************************************************************************** */
25 #include "lib/stdint.h"
26 #include "lib/errno.h"
27 #include "core/system.h"
28 #include "drivers/i2c.h"
29 #include "extdrv/veml6070_uv_sensor.h"
33 /* Check the sensor presence, return 1 if found */
34 int veml6070_probe_sensor(struct veml6070_sensor_config* conf)
35 {
36     char cmd_buf = (conf->addr | I2C_READ_BIT);
38     /* Did we already probe the sensor ? */
39     if (conf->probe_ok != 1) {
40         conf->probe_ok = i2c_read(conf->bus_num, &cmd_buf, 1, NULL, NULL, 0);
41     }
42     return conf->probe_ok;
43 }
45 /* UV Read
46  * Performs a read of the uv data from the sensor.
47  * 'uv_raw': integer addresses for conversion result.
48  * Return value(s):
49  *   Upon successfull completion, returns 0 and the luminosity read is placed in the
50  *   provided integer(s). On error, returns a negative integer equivalent to errors from
51  *   glibc.
52  *   -EBADFD : I2C not initialized
53  *   -EBUSY : Device or ressource Busy or Arbitration lost
54  *   -EINVAL : Invalid argument (buf)
55  *   -ENODEV : No such device
56  *   -EREMOTEIO : Device did not acknowledge : Any device present ?
57  *   -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine
58  */
59 int veml6070_sensor_read(struct veml6070_sensor_config* conf, uint16_t* uv_raw)
60 {
61     int ret = 0;
62     char cmd_buf =0;
63     uint8_t data = 0;
65     if (veml6070_probe_sensor(conf) != 1) {
66         return -ENODEV;
67     }
68     if (uv_raw == NULL) {
69         return -EINVAL;
70     }
72         /* Start by reading MSB */
73         cmd_buf = ((conf->addr + 2) | I2C_READ_BIT);
74     ret = i2c_read(conf->bus_num, &cmd_buf, 1, NULL, &data, 1);
75     if (ret != 1) {
76         return ret;
77     }
78     *uv_raw = ((uint16_t)data << 8) & 0xFF00;
79     msleep(1);
80         /* And read LSB */
81     cmd_buf = (conf->addr | I2C_READ_BIT);
82     ret = i2c_read(conf->bus_num, &cmd_buf, 1, NULL, &data, 1);
83     if (ret != 1) {
84         return ret;
85     }
86     *uv_raw |= (uint16_t)data & 0x00FF;
88     return 0;
89 }
92 /* Sensor config
93  * Performs default configuration of the UV sensor.
94  * Return value:
95  *   Upon successfull completion, returns 0. On error, returns a negative integer
96  *   equivalent to errors from glibc.
97  *   -EBADFD : I2C not initialized
98  *   -EBUSY : Device or ressource Busy or Arbitration lost
99  *   -EINVAL : Invalid argument (buf)
100  *   -ENODEV : No such device
101  *   -EREMOTEIO : Device did not acknowledge : Any device present ?
102  *   -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine
103  */
104 #define CONF_BUF_SIZE 2
105 int veml6070_configure(struct veml6070_sensor_config* conf)
107     int ret = 0;
108     char cmd_buf[CONF_BUF_SIZE] = { conf->addr, (VEML6070_NO_ACK | VEML6070_INTEG_1T | VEML6070_ENABLE), };
110     if (veml6070_probe_sensor(conf) != 1) {
111         return -ENODEV;
112     }
113         msleep(1);
114     ret = i2c_write(conf->bus_num, cmd_buf, CONF_BUF_SIZE, NULL);
115     if (ret != CONF_BUF_SIZE) {
116         return -EIO;
117     }
118     return 0;