From ac3229b75d34e4a6ae310a93493a132619c22d15 Mon Sep 17 00:00:00 2001 From: Nathael Pajani Date: Tue, 13 Sep 2016 18:31:31 +0200 Subject: [PATCH] VEML6070 I2C UV sensor driver --- extdrv/veml6070_uv_sensor.c | 123 ++++++++++++++++++++++++++++ include/extdrv/veml6070_uv_sensor.h | 88 ++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 extdrv/veml6070_uv_sensor.c create mode 100644 include/extdrv/veml6070_uv_sensor.h diff --git a/extdrv/veml6070_uv_sensor.c b/extdrv/veml6070_uv_sensor.c new file mode 100644 index 0000000..5f019a3 --- /dev/null +++ b/extdrv/veml6070_uv_sensor.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * extdrv/veml6070_uv_sensor.c + * + * VEML6070 I2C UV sensor driver + * + * Copyright 2016 Nathael Pajani + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + *************************************************************************** */ + + +#include "lib/stdint.h" +#include "lib/errno.h" +#include "core/system.h" +#include "drivers/i2c.h" +#include "extdrv/veml6070_uv_sensor.h" + + + +/* Check the sensor presence, return 1 if found */ +int veml6070_probe_sensor(struct veml6070_sensor_config* conf) +{ + char cmd_buf = (conf->addr | I2C_READ_BIT); + + /* Did we already probe the sensor ? */ + if (conf->probe_ok != 1) { + conf->probe_ok = i2c_read(conf->bus_num, &cmd_buf, 1, NULL, NULL, 0); + } + return conf->probe_ok; +} + +/* UV Read + * Performs a read of the uv data from the sensor. + * 'uv_raw': integer addresses for conversion result. + * Return value(s): + * Upon successfull completion, returns 0 and the luminosity read is placed in the + * provided integer(s). On error, returns a negative integer equivalent to errors from + * glibc. + * -EBADFD : I2C not initialized + * -EBUSY : Device or ressource Busy or Arbitration lost + * -EINVAL : Invalid argument (buf) + * -ENODEV : No such device + * -EREMOTEIO : Device did not acknowledge : Any device present ? + * -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine + */ +int veml6070_sensor_read(struct veml6070_sensor_config* conf, uint16_t* uv_raw) +{ + int ret = 0; + char cmd_buf =0; + uint8_t data = 0; + + if (veml6070_probe_sensor(conf) != 1) { + return -ENODEV; + } + if (uv_raw == NULL) { + return -EINVAL; + } + + /* Start by reading MSB */ + cmd_buf = ((conf->addr + 2) | I2C_READ_BIT); + ret = i2c_read(conf->bus_num, &cmd_buf, 1, NULL, &data, 1); + if (ret != 1) { + return ret; + } + *uv_raw = ((uint16_t)data << 8) & 0xFF00; + msleep(1); + /* And read LSB */ + cmd_buf = (conf->addr | I2C_READ_BIT); + ret = i2c_read(conf->bus_num, &cmd_buf, 1, NULL, &data, 1); + if (ret != 1) { + return ret; + } + *uv_raw |= (uint16_t)data & 0x00FF; + + return 0; +} + + +/* Sensor config + * Performs default configuration of the UV sensor. + * Return value: + * Upon successfull completion, returns 0. On error, returns a negative integer + * equivalent to errors from glibc. + * -EBADFD : I2C not initialized + * -EBUSY : Device or ressource Busy or Arbitration lost + * -EINVAL : Invalid argument (buf) + * -ENODEV : No such device + * -EREMOTEIO : Device did not acknowledge : Any device present ? + * -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine + */ +#define CONF_BUF_SIZE 2 +int veml6070_configure(struct veml6070_sensor_config* conf) +{ + int ret = 0; + char cmd_buf[CONF_BUF_SIZE] = { conf->addr, (VEML6070_NO_ACK | VEML6070_INTEG_1T | VEML6070_ENABLE), }; + + if (veml6070_probe_sensor(conf) != 1) { + return -ENODEV; + } + msleep(1); + ret = i2c_write(conf->bus_num, cmd_buf, CONF_BUF_SIZE, NULL); + if (ret != CONF_BUF_SIZE) { + return -EIO; + } + return 0; +} + + + + diff --git a/include/extdrv/veml6070_uv_sensor.h b/include/extdrv/veml6070_uv_sensor.h new file mode 100644 index 0000000..bcdba83 --- /dev/null +++ b/include/extdrv/veml6070_uv_sensor.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * extdrv/veml6070_uv_sensor.h + * + * VEML6070 I2C UV sensor driver + * + * Copyright 2016 Nathael Pajani + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + *************************************************************************** */ + + +#include "lib/stdint.h" + + + +/* VEML6070 sensor instance data. + * Note that the veml6070 sensor adress cannot be changed. + */ +struct veml6070_sensor_config { + uint8_t addr; + uint8_t bus_num; + uint8_t probe_ok; + uint8_t actual_config; +}; + + +/* Defines for command byte */ +#define VEML6070_ACK (1 << 5) +#define VEML6070_ACK_THD_102 (0) +#define VEML6070_ACK_THD_145 (1 << 4) +#define VEML6070_NO_ACK (0) +#define VEML6070_INTEG_05T (0x00 << 2) +#define VEML6070_INTEG_1T (0x01 << 2) +#define VEML6070_INTEG_2T (0x02 << 2) +#define VEML6070_INTEG_4T (0x03 << 2) +#define VEML6070_ENABLE (1 << 0) + + +/* Check the sensor presence, return 1 if foundZ */ +int veml6070_probe_sensor(struct veml6070_sensor_config* conf); + + +/* UV Read + * Performs a read of the uv data from the sensor. + * 'uv_raw': integer addresses for conversion result. + * Return value(s): + * Upon successfull completion, returns 0 and the luminosity read is placed in the + * provided integer(s). On error, returns a negative integer equivalent to errors from + * glibc. + * -EBADFD : I2C not initialized + * -EBUSY : Device or ressource Busy or Arbitration lost + * -EINVAL : Invalid argument (buf) + * -ENODEV : No such device + * -EREMOTEIO : Device did not acknowledge : Any device present ? + * -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine + */ +int veml6070_sensor_read(struct veml6070_sensor_config* conf, uint16_t* uv_raw); + + +/* Sensor config + * Performs default configuration of the UV sensor. + * Return value: + * Upon successfull completion, returns 0. On error, returns a negative integer + * equivalent to errors from glibc. + * -EBADFD : I2C not initialized + * -EBUSY : Device or ressource Busy or Arbitration lost + * -EINVAL : Invalid argument (buf) + * -ENODEV : No such device + * -EREMOTEIO : Device did not acknowledge : Any device present ? + * -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine + */ +#define CONF_BUF_SIZE 2 +int veml6070_configure(struct veml6070_sensor_config* conf); + + -- 2.43.0