diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 9d61c4fd8dc..6576c8b9242 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -320,6 +320,22 @@ config SENSORS_MLX90393 ---help--- Enable driver support for the Melex MLX90393 3-Axis magnetometer. +config SENSORS_MLX90614 + bool "MLX90614 Infrared Thermometer" + default n + select I2C + ---help--- + Enable driver support for the Melexis MLX90614 Infrared Thermometer. + +if SENSORS_MLX90614 +config MLX90614_CRC + bool "Enable CRC Checking (verify if PEC field is valid)" + default n + ---help--- + Enable checking of CRC-8 (PEC field) checking to guarantee that + read data is valid. +endif + config SENSORS_MCP9844 bool "MCP9844 Temperature Sensor" default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index 381272202ce..060b1e6676c 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -133,6 +133,10 @@ ifeq ($(CONFIG_SENSORS_MLX90393),y) CSRCS += mlx90393.c endif +ifeq ($(CONFIG_SENSORS_MLX90614),y) + CSRCS += mlx90614.c +endif + ifeq ($(CONFIG_SENSORS_MS58XX),y) CSRCS += ms58xx.c endif diff --git a/drivers/sensors/mlx90614.c b/drivers/sensors/mlx90614.c new file mode 100644 index 00000000000..6209be34b55 --- /dev/null +++ b/drivers/sensors/mlx90614.c @@ -0,0 +1,464 @@ +/**************************************************************************** + * drivers/sensors/mlx90614.c + * Character driver for the Melexis MLX90614 Infrared Thermometer + * + * Copyright (C) 2018 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_MLX90614_CRC +#include +#endif + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_MLX90614) + +/**************************************************************************** + * Pre-process Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mlx90614_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* I2C Helpers */ + +static int mlx90614_read_word(FAR struct mlx90614_dev_s *priv, + uint8_t cmd, FAR uint16_t *regval); +static int mlx90614_write_word(FAR struct mlx90614_dev_s *priv, + uint8_t cmd, uint16_t regval); + +/* Character driver methods */ + +static int mlx90614_open(FAR struct file *filep); +static int mlx90614_close(FAR struct file *filep); +static ssize_t mlx90614_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t mlx90614_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen); +static int mlx90614_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_mlx90614_fops = +{ + mlx90614_open, /* open */ + mlx90614_close, /* close */ + mlx90614_read, /* read */ + mlx90614_write, /* write */ + NULL, /* seek */ + mlx90614_ioctl /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , NULL /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mlx90614_read_word + * + * Description: + * Read 16-bit register + * + ****************************************************************************/ + +static int mlx90614_read_word(FAR struct mlx90614_dev_s *priv, uint8_t cmd, + FAR uint16_t *regval) +{ + struct i2c_config_s config; +#ifdef CONFIG_MLX90614_CRC + uint8_t checkcrc[6]; + uint8_t *buffer; +#else + uint8_t buffer[3]; +#endif + uint8_t crc; + int ret; + +#ifdef CONFIG_MLX90614_CRC + /* Recreate the I2C byte sequence to check the CRC PEC field */ + + checkcrc[0] = I2C_WRITEADDR8(priv->addr); + checkcrc[1] = cmd; + checkcrc[2] = I2C_READADDR8(priv->addr); + + /* Point "buffer" to checkcrc[3] to fill it with received bytes */ + + buffer = (uint8_t *) &checkcrc[3]; +#endif + + /* Set up the I2C configuration */ + + config.frequency = 100000; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the Command and read 16-bits + PEC from the device */ + + ret = i2c_writeread(priv->i2c, &config, (FAR const uint8_t *) &cmd, 1, + buffer, 3); + if (ret < 0) + { + snerr ("i2c_writeread failed: %d\n", ret); + return ret; + } + + /* Copy the content of the buffer to the location of the uint16_t pointer */ + + *regval = (uint16_t)(buffer[0] | (buffer[1] << 8)); + + sninfo("value[0]: %02x | value[1]: %02x | value[2]: %02x | ret: %d\n", + buffer[0], buffer[1], buffer[2], ret); + +#ifdef CONFIG_MLX90614_CRC + crc = crc8ccitt(checkcrc, 5); + sninfo("Calculated CRC: 0x%02X\n", crc); + + if (crc != buffer[2]) + { + snerr("Invalid CRC! Expected: 0x%02X read: 0x%02X\n", crc, buffer[2]); + return -EFAULT; + } +#endif + + return OK; +} + +/**************************************************************************** + * Name: mlx90614_write_word + * + * Description: + * Write to a 16-bit register + * + ****************************************************************************/ + +static int mlx90614_write_word(FAR struct mlx90614_dev_s *priv, uint8_t cmd, + uint16_t regval) +{ + struct i2c_config_s config; + uint8_t pkgcrc[5]; + uint8_t crc; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = 100000; + config.address = priv->addr; + config.addrlen = 7; + + /* First write 0x00 0x00 to erase the EEPROM */ + + pkgcrc[0] = cmd; + pkgcrc[1] = 0x00; + pkgcrc[2] = 0x00; + + /* Generate the CRC to put in the PEC field */ + + crc = crc8ccitt(pkgcrc, 3); + sninfo("Generated CRC: 0x%02X\n", crc); + + pkgcrc[3] = crc; + + /* Write the Command + 2 Bytes + PEC to device */ + + ret = i2c_write(priv->i2c, &config, (FAR const uint8_t *) pkgcrc, 4); + if (ret < 0) + { + snerr ("i2c_writeread failed: %d\n", ret); + return ret; + } + + /* Wait the EEPROM erase */ + + nxsig_usleep(100 * 1000); + + /* Create the I2C command that will be sent to device */ + + pkgcrc[0] = cmd; + pkgcrc[1] = (regval & 0xff); + pkgcrc[2] = (regval & 0xff00) >> 8; + + /* Generate the CRC to put in the PEC field */ + + crc = crc8ccitt(pkgcrc, 3); + sninfo("Generated CRC: 0x%02X\n", crc); + + pkgcrc[3] = crc; + + /* Write the Command + 2 Bytes + PEC to device */ + + ret = i2c_write(priv->i2c, &config, (FAR const uint8_t *) pkgcrc, 4); + if (ret < 0) + { + snerr ("i2c_writeread failed: %d\n", ret); + return ret; + } + + return OK; +} + +/**************************************************************************** + * Name: mlx90614_open + * + * Description: + * This function is called whenever the MLX90614 device is opened. + * + ****************************************************************************/ + +static int mlx90614_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: mlx90614_close + * + * Description: + * This routine is called when the MLX90614 device is closed. + * + ****************************************************************************/ + +static int mlx90614_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: mlx90614_read + ****************************************************************************/ + +static ssize_t mlx90614_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode; + FAR struct mlx90614_dev_s *priv; + FAR struct mlx90614_temp_s *temp = (FAR struct mlx90614_temp_s *)buffer; + uint8_t cmd; + int ret; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct mlx90614_dev_s *)inode->i_private; + + /* Check if the user is reading the right size */ + + if (buflen != sizeof(struct mlx90614_temp_s)) + { + snerr("ERROR: You need to read 2 bytes from this sensor!\n"); + return -EINVAL; + } + + /* Read Ambient Temperature sensor */ + + cmd = MLX90614_CMD_RAM_ACCESS | MLX90614_TA; + + ret = mlx90614_read_word(priv, cmd, &(temp->ta)); + if (ret < 0) + { + snerr("ERROR: Error reading thermometer sensor!\n"); + return ret; + } + + /* Read Object1 Temperature sensor */ + + cmd = MLX90614_CMD_RAM_ACCESS | MLX90614_TOBJ1; + + ret = mlx90614_read_word(priv, cmd, &(temp->tobj1)); + if (ret < 0) + { + snerr("ERROR: Error reading thermometer sensor!\n"); + return ret; + } + + /* Read Object2 Temperature sensor - some sensor doesn't have it */ + + cmd = MLX90614_CMD_RAM_ACCESS | MLX90614_TOBJ2; + + ret = mlx90614_read_word(priv, cmd, &(temp->tobj2)); + if (ret < 0) + { + snerr("ERROR: Error reading thermometer sensor!\n"); + return ret; + } + + return buflen; +} + +/**************************************************************************** + * Name: mlx90614_write + ****************************************************************************/ + +static ssize_t mlx90614_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: mlx90614_ioctl + ****************************************************************************/ + +static int mlx90614_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct mlx90614_dev_s *priv = inode->i_private; + int ret = OK; + + switch (cmd) + { + /* Change the device to use a new i2c/smbus address */ + + case SNIOC_CHANGE_SMBUSADDR: + { + FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + uint16_t newaddr; + uint8_t smbcmd; + + /* The I2C address is put in the high byte position */ + + newaddr = (uint16_t) (*ptr << 8); + snerr("Setting new address: 0x%02x\n", newaddr); + + smbcmd = MLX90614_CMD_EEPROM_ACCESS | MLX90614_SMBUS_ADDR; + + ret = mlx90614_write_word(priv, smbcmd, newaddr); + if (ret < 0) + { + snerr("ERROR: Failed to change the I2C/SMBus address!\n"); + } + } + break; + + default: + snerr("ERROR: Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mlx90614_register + * + * Description: + * Register the MLX90614 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/therm0" + * i2c - An instance of the I2C interface to use to communicate with + * MLX90614 + * addr - The I2C address of the MLX90614. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int mlx90614_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + int ret; + + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + + /* Initialize the MLX90614 device structure */ + + FAR struct mlx90614_dev_s *priv = + (FAR struct mlx90614_dev_s *)kmm_malloc(sizeof(struct mlx90614_dev_s)); + + if (priv == NULL) + { + snerr("ERROR: Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_mlx90614_fops, 0666, priv); + if (ret < 0) + { + snerr("ERROR: Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_SENSORS_MLX90614 */ + diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h index d39a595b468..aa44308ae1d 100644 --- a/include/nuttx/sensors/ioctl.h +++ b/include/nuttx/sensors/ioctl.h @@ -174,4 +174,8 @@ #define SNIOC_LSM303AGRSENSORREAD _SNIOC(0x0051) /* Arg: file *filep, FAR char *buffer,size_t buflen */ #define SNIOC_START_SELFTEST _SNIOC(0x0052) /* Arg: file *filep, FAR char *buffer,size_t mode */ +/* IOCTL commands unique to the MLX90614 */ + +#define SNIOC_CHANGE_SMBUSADDR _SNIOC(0x0053) /* Arg: uint8_t value */ + #endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */ diff --git a/include/nuttx/sensors/mlx90614.h b/include/nuttx/sensors/mlx90614.h new file mode 100644 index 00000000000..3ed9e035f21 --- /dev/null +++ b/include/nuttx/sensors/mlx90614.h @@ -0,0 +1,188 @@ +/**************************************************************************** + * include/nuttx/sensors/mlx90614.h + * + * Copyright (C) 2018 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SENSORS_MLX90614_H +#define __INCLUDE_NUTTX_SENSORS_MLX90614_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_MLX90614) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* MLX90614 Commands */ + +#define MLX90614_CMD_RAM_ACCESS (0x00) /* RAM Access Command */ +#define MLX90614_CMD_EEPROM_ACCESS (0x20) /* EEPROM Access Command */ +#define MLX90614_CMD_READ_FLAGS (0xf0) /* Read Flags Command */ +#define MLX90614_CMD_ENTER_SLEEP (0xff) /* Enter Sleep Mode Command */ + +/* MLX90614 EEPROM Addresses ************************************************/ + +#define MLX90614_TO_MAX (0x00) /* To_max = Max Temperature of the Object */ +#define MLX90614_TO_MIN (0x01) /* To_min = Min Temperature of the Object */ +#define MLX90614_PWMCTRL (0x02) /* PWM Control */ +#define MLX90614_TA_RANGE (0x03) /* Range of Ambient Temperature */ +#define MLX90614_KE (0x04) /* Ke */ +#define MLX90614_CONFIG_REG1 (0x05) /* Config Register1 */ + /* 0x06-0x0D - Reserved */ +#define MLX90614_SMBUS_ADDR (0x0e) /* SMBus address */ + /* 0x0f-0x1b - Reserved */ +#define MLX90614_ID_NUM1 (0x1c) /* ID number */ +#define MLX90614_ID_NUM2 (0x1d) /* ID number */ +#define MLX90614_ID_NUM3 (0x1e) /* ID number */ +#define MLX90614_ID_NUM4 (0x1f) /* ID number */ + +/* Register bits definitions */ + +/* PWMCTRL */ + +#define PWMCTRL_MODE_SINGLE (1 << 0) /* Single PWM, 0 = Extended PWM */ +#define PWMCTRL_PWM_ENABLE (1 << 1) /* Enable PWM/disable SMBus, 0 = Disable PWM/enable SMBus */ +#define PWMCTRL_PWM_PUSHPULL (1 << 2) /* Push-Pull mode, 0 = OpenDrain */ +#define PWMCTRL_THERMORELAY (1 << 3) /* ThermoRelay mode, 0 = PWM mode */ +#define PWMCTRL_EXT_PWM_SHIFT (4) /* Number of repetitions */ +#define PWMCTRL_EXT_PWM_MASK (0x1f << PWMCTRL_EXT_PWM_SHIFT) +#define PWMCTRL_EXT_PWM_REP(n) (n << PWMCTRL_EXT_PWM_SHIFT) +#define PWMCTRL_PWM_CLK_CFG_SHIFT (9) /* PWM clock configuration */ +#define PWMCTRL_PWM_CLK_CFG_MASK (0x7f << PWMCTRL_PWM_CLK_CFG_SHIFT) +#define PWMCTRL_PWM_CLK_CFG_DIV(n) (n << PWMCTRL_PWM_CLK_CFG_SHIFT) + +/* CONFIG_REG1 */ + +#define CONFIG_REG1_IIR_SHIFT (0) /* Bits 2:0 - Configure IIR Coeficients */ +#define CONFIG_REG1_IIR_MASK (7 << CONFIG_REG1_IIR_SHIFT) +#define CONFIG_REG1_IIR_0p5_0p5 (0 << CONFIG_REG1_IIR_SHIFT) /* a1 = 0.5 and b1 = 0.5 */ +#define CONFIG_REG1_IIR_0p57_0p42 (7 << CONFIG_REG1_IIR_SHIFT) /* a1 = 0.571428571 and b1 = 0.428571428 */ +#define CONFIG_REG1_IIR_0p66_0p33 (6 << CONFIG_REG1_IIR_SHIFT) /* a1 = 0.666... and b1 = 0.333... */ +#define CONFIG_REG1_IIR_0p8_0p2 (5 << CONFIG_REG1_IIR_SHIFT) /* a1 = 0.8 and b1 = 0.2 */ +#define CONFIG_REG1_IIR_BYPASS (4 << CONFIG_REG1_IIR_SHIFT) /* a1 = 1 and b1 = 0 => IIR bypassed */ +#define CONFIG_REG1_AMB_SENSOR_PTC (1 << 3) /* Ambient temperature sensor: 1 = PTC, 0 = PTAT */ +#define CONFIG_REG1_DATA_PWM_SHIFT (4) /* Bits 5:4 - Data transmitted through PWM */ +#define CONFIG_REG1_DATA_PWM_MASK (3 << CONFIG_REG1_DATA_PWM_SHIFT) +#define CONFIG_REG1_DATA_PWM_TA_IR1 (0 << CONFIG_REG1_DATA_PWM_SHIFT) /* Data1 = Ta and Data2 = IR1 */ +#define CONFIG_REG1_DATA_PWM_TA_IR2 (1 << CONFIG_REG1_DATA_PWM_SHIFT) /* Data1 = Ta and Data2 = IR2 */ +#define CONFIG_REG1_DATA_PWM_IR1_IR2 (2 << CONFIG_REG1_DATA_PWM_SHIFT) /* Data1 = IR1 and Data2 = IR2 */ +#define CONFIG_REG1_DATA_PWM_IR1_UND (3 << CONFIG_REG1_DATA_PWM_SHIFT) /* Data1 = IR2 and Data2 = Undefined */ +#define CONFIG_REG1_NUM_SENSORS (1 << 6) /* Number of sensors: 1 = 2 sensors, 0 = 1 sensor */ +#define CONFIG_REG1_KS (1 << 7) /* Define the sign Ks. Factory calibration, do not alter */ +#define CONFIG_REG1_FIR_SHIFT (8) /* Bits 10:8 - Configure coefficient N of FIR digital filter */ +#define CONFIG_REG1_FIR_MASK (7 << CONFIG_REG1_FIR_SHIFT) +#define CONFIG_REG1_FIR_N(n) (((n >> 3) - 1) << CONFIG_REG1_FIR_SHIFT) /* n = 8, 16, 32, 64 ... 1024 */ +#define CONFIG_REG1_AMP_GAIN_SHIFT (11) /* Bits 13:11 - Configure the gain of amplifier */ +#define CONFIG_REG1_AMP_GAIN_MASK (7 << CONFIG_REG1_AMP_GAIN_SHIFT) +#define CONFIG_REG1_AMP_GAIN_1 (0 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 1 => preamplifier bypassed */ +#define CONFIG_REG1_AMP_GAIN_3 (1 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 3 */ +#define CONFIG_REG1_AMP_GAIN_6 (2 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 6 */ +#define CONFIG_REG1_AMP_GAIN_12p5 (3 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 12.5 */ +#define CONFIG_REG1_AMP_GAIN_25 (4 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 25 */ +#define CONFIG_REG1_AMP_GAIN_50 (5 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 50 */ +#define CONFIG_REG1_AMP_GAIN_100 (6 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 100 */ +#define CONFIG_REG1_AMP_GAIN_200 (7 << CONFIG_REG1_AMP_GAIN_SHIFT) /* Gain = 200 */ +#define CONFIG_REG1_THERMOSHOCK_NEG (1 << 15) /* Define the sign of thermosock: 1 - negative, 0 - positive */ + +/* MLX90614 RAM Register ****************************************************/ + +#define MLX90614_TA (0x06) /* Ta = Temperature Ambient */ +#define MLX90614_TOBJ1 (0x07) /* Tobj1 = Temperature Object 1 */ +#define MLX90614_TOBJ2 (0x08) /* Tobj2 = Temperature Object 2 */ + +/* MLX90614 Read Flags */ + +#define MLX90614_EEBUSY (1 << 15) /* Previos write/erase EEPROM access is still in progress */ +#define MLX90614_EEDEAD (1 << 13) /* EEPROM double error has occurred */ +#define MLX90614_INIT (1 << 12) /* POR initialization routine is still ongoing */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct mlx90614_temp_s +{ + uint16_t ta; + uint16_t tobj1; + uint16_t tobj2; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: mlx90614_register + * + * Description: + * Register the MLX90614 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/mag0" + * i2c - An instance of the I2C interface to use to communicate with + * MLX90614 + * addr - The I2C address used by the MLX90614. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int mlx90614_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_SENSORS_MLX90614 */ + +#endif /* __INCLUDE_NUTTX_SENSORS_MLX90614_H */ +