[rtems commit] i2c: Add temperature sensor LM75A driver

Sebastian Huber sebh at rtems.org
Mon Oct 2 11:41:32 UTC 2017


Module:    rtems
Branch:    master
Commit:    4cfce5cb6457514947f2ffeba9e3168945cd370d
Changeset: http://git.rtems.org/rtems/commit/?id=4cfce5cb6457514947f2ffeba9e3168945cd370d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Sep 28 08:13:01 2017 +0200

i2c: Add temperature sensor LM75A driver

Close #3163.

---

 cpukit/dev/Makefile.am                    |   2 +
 cpukit/dev/i2c/sensor-lm75a.c             | 198 ++++++++++++++++++++++++++++++
 cpukit/dev/include/dev/i2c/sensor-lm75a.h | 125 +++++++++++++++++++
 cpukit/dev/preinstall.am                  |   4 +
 4 files changed, 329 insertions(+)

diff --git a/cpukit/dev/Makefile.am b/cpukit/dev/Makefile.am
index debb084..b60e035 100644
--- a/cpukit/dev/Makefile.am
+++ b/cpukit/dev/Makefile.am
@@ -10,6 +10,7 @@ include_dev_i2c_HEADERS += include/dev/i2c/eeprom.h
 include_dev_i2c_HEADERS += include/dev/i2c/fpga-i2c-slave.h
 include_dev_i2c_HEADERS += include/dev/i2c/gpio-nxp-pca9535.h
 include_dev_i2c_HEADERS += include/dev/i2c/i2c.h
+include_dev_i2c_HEADERS += include/dev/i2c/sensor-lm75a.h
 include_dev_i2c_HEADERS += include/dev/i2c/switch-nxp-pca9548a.h
 include_dev_i2c_HEADERS += include/dev/i2c/xilinx-axi-i2c.h
 include_dev_i2c_HEADERS += include/dev/i2c/ti-ads-16bit-adc.h
@@ -41,6 +42,7 @@ libdev_a_SOURCES += i2c/fpga-i2c-slave.c
 libdev_a_SOURCES += i2c/gpio-nxp-pca9535.c
 libdev_a_SOURCES += i2c/i2c-bus.c
 libdev_a_SOURCES += i2c/i2c-dev.c
+libdev_a_SOURCES += i2c/sensor-lm75a.c
 libdev_a_SOURCES += i2c/switch-nxp-pca9548a.c
 libdev_a_SOURCES += i2c/xilinx-axi-i2c.c
 libdev_a_SOURCES += i2c/ti-ads-16bit-adc.c
diff --git a/cpukit/dev/i2c/sensor-lm75a.c b/cpukit/dev/i2c/sensor-lm75a.c
new file mode 100644
index 0000000..4cc1ae6
--- /dev/null
+++ b/cpukit/dev/i2c/sensor-lm75a.c
@@ -0,0 +1,198 @@
+/**
+ * @file
+ *
+ * @brief Temperature Sensor LM75A Driver Implementation
+ *
+ * @ingroup I2CSensorLM75A
+ */
+
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dev/i2c/sensor-lm75a.h>
+
+typedef enum {
+  SENSOR_LM75A_PTR_TEMP,
+  SENSOR_LM75A_PTR_CONF,
+  SENSOR_LM75A_PTR_THYST,
+  SENSOR_LM75A_PTR_TOS
+} sensor_lm75a_ptr;
+
+static int sensor_lm75a_get_reg_8(
+  i2c_dev *dev,
+  sensor_lm75a_ptr ptr,
+  uint8_t *val
+)
+{
+  uint8_t out[1] = { ptr };
+  uint8_t in[sizeof(*val)];
+  i2c_msg msgs[2] = {
+    {
+      .addr = dev->address,
+      .flags = 0,
+      .len = (uint16_t) sizeof(out),
+      .buf = &out[0]
+    }, {
+      .addr = dev->address,
+      .flags = I2C_M_RD,
+      .len = (uint16_t) sizeof(in),
+      .buf = &in[0]
+    }
+  };
+  int err;
+
+  err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
+  *val = in[0];
+
+  return err;
+}
+
+static int sensor_lm75a_set_reg_8(
+  i2c_dev *dev,
+  sensor_lm75a_ptr ptr,
+  uint8_t val
+)
+{
+  uint8_t out[2] = { ptr, val };
+  i2c_msg msgs[1] = {
+    {
+      .addr = dev->address,
+      .flags = 0,
+      .len = (uint16_t) sizeof(out),
+      .buf = &out[0]
+    }
+  };
+
+  return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
+}
+
+static int sensor_lm75a_get_reg_16(
+  i2c_dev *dev,
+  sensor_lm75a_ptr ptr,
+  uint16_t *val
+)
+{
+  uint8_t out[1] = { ptr };
+  uint8_t in[sizeof(*val)];
+  i2c_msg msgs[2] = {
+    {
+      .addr = dev->address,
+      .flags = 0,
+      .len = (uint16_t) sizeof(out),
+      .buf = &out[0]
+    }, {
+      .addr = dev->address,
+      .flags = I2C_M_RD,
+      .len = (uint16_t) sizeof(in),
+      .buf = &in[0]
+    }
+  };
+  int err;
+
+  err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
+  *val = (in[0] << 8) | in[1];
+
+  return err;
+}
+
+static int sensor_lm75a_set_reg_16(
+  i2c_dev *dev,
+  sensor_lm75a_ptr ptr,
+  uint16_t val
+)
+{
+  uint8_t out[3] = { ptr, (uint8_t) (val >> 8), (uint8_t) val };
+  i2c_msg msgs[1] = {
+    {
+      .addr = dev->address,
+      .flags = 0,
+      .len = (uint16_t) sizeof(out),
+      .buf = &out[0]
+    }
+  };
+
+  return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
+}
+
+static int sensor_lm75a_ioctl(
+  i2c_dev *dev,
+  ioctl_command_t command,
+  void *arg
+)
+{
+  uint8_t v8 = (uint8_t) (uintptr_t) arg;
+  uint16_t v16 = (uint16_t) (uintptr_t) arg;
+  int err;
+
+  switch (command) {
+    case SENSOR_LM75A_GET_CONF:
+      err = sensor_lm75a_get_reg_8(dev, SENSOR_LM75A_PTR_CONF, arg);
+      break;
+    case SENSOR_LM75A_SET_CONF:
+      err = sensor_lm75a_set_reg_8(dev, SENSOR_LM75A_PTR_CONF, v8);
+      break;
+    case SENSOR_LM75A_CLEAR_AND_SET_CONF:
+      i2c_bus_obtain(dev->bus);
+      err = sensor_lm75a_get_reg_8(dev, SENSOR_LM75A_PTR_CONF, &v8);
+      if (err == 0) {
+        v8 &= ~((uint8_t) v16);
+        v8 |= (uint8_t) (v16 >> 8);
+        err = sensor_lm75a_set_reg_8(dev, SENSOR_LM75A_PTR_CONF, v8);
+      }
+      i2c_bus_release(dev->bus);
+      break;
+    case SENSOR_LM75A_GET_TEMP:
+      err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_TEMP, arg);
+      break;
+    case SENSOR_LM75A_GET_TOS:
+      err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_TOS, arg);
+      break;
+    case SENSOR_LM75A_SET_TOS:
+      err = sensor_lm75a_set_reg_16(dev, SENSOR_LM75A_PTR_TOS, v16);
+      break;
+    case SENSOR_LM75A_GET_THYST:
+      err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_THYST, arg);
+      break;
+    case SENSOR_LM75A_SET_THYST:
+      err = sensor_lm75a_set_reg_16(dev, SENSOR_LM75A_PTR_THYST, v16);
+      break;
+    default:
+      err = -ENOTTY;
+      break;
+  }
+
+  return err;
+}
+
+int i2c_dev_register_sensor_lm75a(
+  const char *bus_path,
+  const char *dev_path,
+  uint16_t address
+)
+{
+  i2c_dev *dev;
+
+  dev = i2c_dev_alloc_and_init(sizeof(*dev), bus_path, address);
+  if (dev == NULL) {
+    return -1;
+  }
+
+  dev->ioctl = sensor_lm75a_ioctl;
+
+  return i2c_dev_register(dev, dev_path);
+}
diff --git a/cpukit/dev/include/dev/i2c/sensor-lm75a.h b/cpukit/dev/include/dev/i2c/sensor-lm75a.h
new file mode 100644
index 0000000..e1957da
--- /dev/null
+++ b/cpukit/dev/include/dev/i2c/sensor-lm75a.h
@@ -0,0 +1,125 @@
+/**
+ * @file
+ *
+ * @brief Temperature Sensor LM75A Driver API
+ *
+ * @ingroup I2CSensorLM75A
+ */
+
+/*
+ * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _DEV_I2C_SENSOR_LM75A_H
+#define _DEV_I2C_SENSOR_LM75A_H
+
+#include <dev/i2c/i2c.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup I2CSensorLM75A Temperature Sensor LM75A Driver
+ *
+ * @ingroup I2CDevice
+ *
+ * @brief Driver for NXP or Texas Instruments LM75A temperature sensor.
+ *
+ * @{
+ */
+
+int i2c_dev_register_sensor_lm75a(
+  const char *bus_path,
+  const char *dev_path,
+  uint16_t address
+);
+
+typedef enum {
+  SENSOR_LM75A_GET_CONF = I2C_DEV_IO_CONTROL,
+  SENSOR_LM75A_SET_CONF,
+  SENSOR_LM75A_CLEAR_AND_SET_CONF,
+  SENSOR_LM75A_GET_TEMP,
+  SENSOR_LM75A_GET_TOS,
+  SENSOR_LM75A_SET_TOS,
+  SENSOR_LM75A_GET_THYST,
+  SENSOR_LM75A_SET_THYST
+} sensor_lm75a_command;
+
+static inline int sensor_lm75a_get_conf(int fd, uint8_t *val)
+{
+  return ioctl(fd, SENSOR_LM75A_GET_CONF, val);
+}
+
+static inline int sensor_lm75a_set_conf(int fd, uint8_t val)
+{
+  return ioctl(fd, SENSOR_LM75A_SET_CONF, (void *)(uintptr_t) val);
+}
+
+static inline int sensor_lm75a_clear_and_set_conf(
+  int fd,
+  uint8_t clear,
+  uint8_t set
+)
+{
+  uint16_t clear_and_set = (uint16_t) (((uint16_t) set << 8) | clear);
+
+  return ioctl(
+    fd,
+    SENSOR_LM75A_CLEAR_AND_SET_CONF,
+    (void *)(uintptr_t) clear_and_set
+  );
+}
+
+static inline int sensor_lm75a_get_temp(int fd, int16_t *val)
+{
+  return ioctl(fd, SENSOR_LM75A_GET_TEMP, val);
+}
+
+static inline int sensor_lm75a_get_temp_celsius(int fd, double *celsius)
+{
+  int rv;
+  int16_t val;
+
+  rv = ioctl(fd, SENSOR_LM75A_GET_TEMP, &val);
+  *celsius = (((int) val) >> 5) * 0.125;
+  return rv;
+}
+
+static inline int sensor_lm75a_get_tos(int fd, uint16_t *val)
+{
+  return ioctl(fd, SENSOR_LM75A_GET_TOS, val);
+}
+
+static inline int sensor_lm75a_set_tos(int fd, uint16_t val)
+{
+  return ioctl(fd, SENSOR_LM75A_SET_TOS, (void *)(uintptr_t) val);
+}
+
+static inline int sensor_lm75a_get_thyst(int fd, uint16_t *val)
+{
+  return ioctl(fd, SENSOR_LM75A_GET_THYST, val);
+}
+
+static inline int sensor_lm75a_set_thyst(int fd, uint16_t val)
+{
+  return ioctl(fd, SENSOR_LM75A_SET_THYST, (void *)(uintptr_t) val);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _DEV_I2C_SENSOR_LM75A_H */
diff --git a/cpukit/dev/preinstall.am b/cpukit/dev/preinstall.am
index fd35488..4cb1dce 100644
--- a/cpukit/dev/preinstall.am
+++ b/cpukit/dev/preinstall.am
@@ -39,6 +39,10 @@ $(PROJECT_INCLUDE)/dev/i2c/i2c.h: include/dev/i2c/i2c.h $(PROJECT_INCLUDE)/dev/i
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dev/i2c/i2c.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/dev/i2c/i2c.h
 
+$(PROJECT_INCLUDE)/dev/i2c/sensor-lm75a.h: include/dev/i2c/sensor-lm75a.h $(PROJECT_INCLUDE)/dev/i2c/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dev/i2c/sensor-lm75a.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/dev/i2c/sensor-lm75a.h
+
 $(PROJECT_INCLUDE)/dev/i2c/switch-nxp-pca9548a.h: include/dev/i2c/switch-nxp-pca9548a.h $(PROJECT_INCLUDE)/dev/i2c/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/dev/i2c/switch-nxp-pca9548a.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/dev/i2c/switch-nxp-pca9548a.h




More information about the vc mailing list