summaryrefslogtreecommitdiffstats
path: root/cpukit/dev/include
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2017-08-16 15:10:33 +1000
committerChris Johns <chrisj@rtems.org>2017-08-20 10:59:53 +1000
commit849500d0f226e9aa81cbfddf7c09c0f83a7568f9 (patch)
treea54b6d9cf56e5f531140ad67ea4144e7faacd4f6 /cpukit/dev/include
parentdev/i2c: Add Xilinx AXI I2C driver. (diff)
downloadrtems-849500d0f226e9aa81cbfddf7c09c0f83a7568f9.tar.bz2
dev/i2c: Add I2C device support for FPGA Slave, LM25066A, TMP112, ADS1113, ADS1114 and ADS1115
Closes #3101.
Diffstat (limited to 'cpukit/dev/include')
-rw-r--r--cpukit/dev/include/dev/i2c/fpga-i2c-slave.h25
-rw-r--r--cpukit/dev/include/dev/i2c/ti-ads-16bit-adc.h203
-rw-r--r--cpukit/dev/include/dev/i2c/ti-lm25066a.h190
-rw-r--r--cpukit/dev/include/dev/i2c/ti-tmp112.h109
4 files changed, 527 insertions, 0 deletions
diff --git a/cpukit/dev/include/dev/i2c/fpga-i2c-slave.h b/cpukit/dev/include/dev/i2c/fpga-i2c-slave.h
new file mode 100644
index 0000000000..c10b26ac5b
--- /dev/null
+++ b/cpukit/dev/include/dev/i2c/fpga-i2c-slave.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * I2C slave for testing:
+ * https://github.com/oetr/FPGA-I2C-Slave
+ */
+
+#ifndef FPGA_I2C_SLAVE_H
+#define FPGA_I2C_SLAVE_H
+
+#include <dev/i2c/i2c.h>
+
+int i2c_dev_register_fpga_i2c_slave(const char* bus_path,
+ const char* dev_path,
+ uint16_t address,
+ size_t size);
+
+#endif
diff --git a/cpukit/dev/include/dev/i2c/ti-ads-16bit-adc.h b/cpukit/dev/include/dev/i2c/ti-ads-16bit-adc.h
new file mode 100644
index 0000000000..40d680da88
--- /dev/null
+++ b/cpukit/dev/include/dev/i2c/ti-ads-16bit-adc.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * TI ADS1113 and ADS1115.
+ * http://www.ti.com/product/ads1113/description
+ */
+
+#ifndef TI_ADS1113_ADS1115_H
+#define TI_ADS1113_ADS1115_H
+
+#include <dev/i2c/i2c.h>
+
+/*
+ * Supported devices. Please others once tested.
+ */
+typedef enum {
+ TI_ADS1113,
+ TI_ADS1114,
+ TI_ADS1115
+} ti_ads_adc;
+
+/*
+ * Multiplexer interface. Avalable on ADS1115.
+ */
+typedef enum {
+ TI_ADS_MUX_ApA0_AnA1 = 0, /* default */
+ TI_ADS_MUX_ApA0_AnA3 = 1,
+ TI_ADS_MUX_ApA1_AnA3 = 2,
+ TI_ADS_MUX_ApA2_AnA3 = 3,
+ TI_ADS_MUX_ApA0_AnGND = 4,
+ TI_ADS_MUX_ApA1_AnGND = 5,
+ TI_ADS_MUX_ApA2_AnGND = 6,
+ TI_ADS_MUX_ApA3_AnGND = 7
+} ti_ads_adc_mux;
+
+/*
+ * Programmable Gain Amplifier. Avalable on ADS1114 and ADS1115.
+ */
+typedef enum {
+ TI_ADS_PGA_FS_6_144V = 0,
+ TI_ADS_PGA_FS_4_096V = 1,
+ TI_ADS_PGA_FS_2_048V = 2, /* default */
+ TI_ADS_PGA_FS_1_024V = 3,
+ TI_ADS_PGA_FS_0_512V = 4,
+ TI_ADS_PGA_FS_0_256V = 5,
+ TI_ADS_PGA_FS_0_256V_2 = 6,
+ TI_ADS_PGA_FS_0_256V_3 = 7,
+} ti_ads_adc_pga;
+
+/*
+ * Mode.
+ */
+typedef enum {
+ TI_ADS_MODE_CONTINUOUS = 0,
+ TI_ADS_MODE_SINGLE_SHOT = 1, /* default */
+} ti_ads_adc_mode;
+
+/*
+ * Data rate.
+ */
+typedef enum {
+ TI_ADS_DATARATE_8SPS = 0,
+ TI_ADS_DATARATE_16SPS = 1,
+ TI_ADS_DATARATE_32SPS = 2,
+ TI_ADS_DATARATE_64SPS = 3,
+ TI_ADS_DATARATE_128SPS = 4, /* default */
+ TI_ADS_DATARATE_250SPS = 5,
+ TI_ADS_DATARATE_475SPS = 6,
+ TI_ADS_DATARATE_860SPS = 7,
+} ti_ads_adc_data_rate;
+
+/*
+ * Comparitor interface. Avalable on ADS1114 and ADS1115.
+ *
+ * Create a value to write.
+ */
+#define TI_ADS_COMP_MODE_HYSTERESIS (0 << 4) /* default */
+#define TI_ADS_COMP_MODE_WINDOW (1 << 4)
+#define TI_ADS_COMP_POL_ACTIVE_LOW (0 << 3) /* default */
+#define TI_ADS_COMP_POL_ACTIVE_HIGH (1 << 3)
+#define TI_ADS_COMP_LAT_NON_LATCHING (0 << 2) /* default */
+#define TI_ADS_COMP_LAT_LATCHING (1 << 2)
+#define TI_ADS_COMP_QUE_DISABLE_COMP (3 << 0) /* default */
+#define TI_ADS_COMP_QUE_AFTER_4 (2 << 0)
+#define TI_ADS_COMP_QUE_AFTER_2 (1 << 0)
+#define TI_ADS_COMP_QUE_AFTER_1 (0 << 0)
+
+/*
+ * IO control interface.
+ *
+ * Note: if in Power-down single-shot mode (default) a conversion requires the
+ * device to power up and perform a conversion and this can take
+ * while. The TI_ADS_ADC_GET_CONV_WAIT call sets the micro-seconds to
+ * wait between polls. The actual rate will depend on the system tick.
+ */
+#define TI_ADS_ADC_GET_CONVERSION (I2C_DEV_IO_CONTROL + 0)
+#define TI_ADS_ADC_SET_MUX (I2C_DEV_IO_CONTROL + 1)
+#define TI_ADS_ADC_SET_PGA (I2C_DEV_IO_CONTROL + 2)
+#define TI_ADS_ADC_SET_MODE (I2C_DEV_IO_CONTROL + 3)
+#define TI_ADS_ADC_SET_DATA_RATE (I2C_DEV_IO_CONTROL + 4)
+#define TI_ADS_ADC_SET_COMP (I2C_DEV_IO_CONTROL + 5)
+#define TI_ADS_ADC_SET_LO_THRESH (I2C_DEV_IO_CONTROL + 6)
+#define TI_ADS_ADC_SET_HI_THRESH (I2C_DEV_IO_CONTROL + 7)
+#define TI_ADS_ADC_SET_CONV_WAIT (I2C_DEV_IO_CONTROL + 8)
+
+/*
+ * Register the device.
+ */
+int i2c_dev_register_ti_ads_adc(const char* bus_path,
+ const char* dev_path,
+ uint16_t address,
+ ti_ads_adc device);
+
+/*
+ * Perform a conversion. If the mode is single shot a single shot conversion is
+ * started and the call waits for the conversion to complete.
+ */
+static inline int
+ti_ads_adc_convert(int fd, uint16_t* sample)
+{
+ return ioctl(fd, TI_ADS_ADC_GET_CONVERSION, sample);
+}
+
+/*
+ * Set the multipler.
+ */
+static inline int
+ti_ads_adc_set_mux(int fd, ti_ads_adc_mux mux)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_MUX, (void *)(uintptr_t) mux);
+}
+
+/*
+ * Set the PGA.
+ */
+static inline int
+ti_ads_adc_set_pga(int fd, ti_ads_adc_pga pga)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_PGA, (void *)(uintptr_t) pga);
+}
+
+/*
+ * Set the mode.
+ */
+static inline int
+ti_ads_adc_set_mode(int fd, ti_ads_adc_mode mode)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_MODE, (void *)(uintptr_t) mode);
+}
+
+/*
+ * Set the data rate.
+ */
+static inline int
+ti_ads_adc_set_data_rate(int fd, ti_ads_adc_data_rate rate)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_DATA_RATE, (void *)(uintptr_t) rate);
+}
+
+/*
+ * Configure the comparator.
+ */
+static inline int
+ti_ads_adc_set_comparator(int fd, uint16_t comp)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_COMP, (void *)(uintptr_t) comp);
+}
+
+/*
+ * Set the lower threshold.
+ */
+static inline int
+ti_ads_adc_set_low_threshold(int fd, uint16_t level)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_LO_THRESH, (void *)(uintptr_t) level);
+}
+
+/*
+ * Set the upper threshold.
+ */
+static inline int
+ti_ads_adc_set_high_threshold(int fd, uint16_t level)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_HI_THRESH, (void *)(uintptr_t) level);
+}
+
+/*
+ * Set the conversion poll wait period.
+ */
+static inline int
+ti_ads_adc_set_conversion_poll_wait(int fd, uint32_t micro_seconds)
+{
+ return ioctl(fd, TI_ADS_ADC_SET_CONV_WAIT, (void *)(uintptr_t) micro_seconds);
+}
+
+#endif
diff --git a/cpukit/dev/include/dev/i2c/ti-lm25066a.h b/cpukit/dev/include/dev/i2c/ti-lm25066a.h
new file mode 100644
index 0000000000..4429f0fc70
--- /dev/null
+++ b/cpukit/dev/include/dev/i2c/ti-lm25066a.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * TI LM25066A
+ * http://www.ti.com/product/LM25066A
+ */
+
+#ifndef TI_LM25066A_H
+#define TI_LM25066A_H
+
+#include <dev/i2c/i2c.h>
+
+/*
+ * PM Bus Command interface.
+ *
+ * The keys are:
+ * IO : IO direction R=read W=write
+ * SZ : Size in bytes.
+ */
+typedef enum
+{ /* IO SZ Name */
+ TI_LM25066A_OPERATION = 0, /* R 1 PMBus */
+ TI_LM25066A_CLEAR_FAULTS = 1, /* W 0 PMBus */
+ TI_LM25066A_CAPABILITY = 2, /* R 1 PMBus */
+ TI_LM25066A_VOUT_UV_WARN_LIMIT = 3, /* RW 2 PMBus */
+ TI_LM25066A_OT_FAULT_LIMIT = 4, /* RW 2 PMBus */
+ TI_LM25066A_OT_WARN_LIMIT = 5, /* RW 2 PMBus */
+ TI_LM25066A_VIN_OV_WARN_LIMIT = 6, /* RW 2 PMBus */
+ TI_LM25066A_VIN_UV_WARN_LIMIT = 7, /* RW 2 PMBus */
+ TI_LM25066A_STATUS_BYTE = 8, /* R 1 PMBus */
+ TI_LM25066A_STATUS_WORD = 9, /* R 2 PMBus */
+ TI_LM25066A_STATUS_VOUT = 10, /* R 1 PMBus */
+ TI_LM25066A_STATUS_INPUT = 11, /* R 1 PMBus */
+ TI_LM25066A_STATUS_TEMPERATURE = 12, /* R 1 PMBus */
+ TI_LM25066A_STATUS_CML = 13, /* R 1 PMBus */
+ TI_LM25066A_STATUS_MFR_SPECIFIC = 14, /* R 1 PMBus */
+ TI_LM25066A_READ_VIN = 15, /* R 2 PMBus */
+ TI_LM25066A_READ_VOUT = 16, /* R 2 PMBus */
+ TI_LM25066A_READ_TEMPERATURE_1 = 17, /* R 2 PMBus */
+ TI_LM25066A_MFR_ID = 18, /* R 3 PMBus */
+ TI_LM25066A_MFR_MODEL = 19, /* R 8 PMBus */
+ TI_LM25066A_MFR_REVISION = 20, /* R 2 PMBus */
+ TI_LM25066A_MFR_READ_VAUX = 21, /* R 2 MFR_SPECIFIC_00 */
+ TI_LM25066A_MFR_READ_IIN = 22, /* R 2 MFR_SPECIFIC_01 */
+ TI_LM25066A_MFR_READ_PIN = 23, /* R 2 MFR_SPECIFIC_02 */
+ TI_LM25066A_MFR_IIN_OC_WARN_LIMIT = 24, /* RW 2 MFR_SPECIFIC_03 */
+ TI_LM25066A_MFR_PIN_OP_WARN_LIMIT = 25, /* RW 2 MFR_SPECIFIC_04 */
+ TI_LM25066A_MFR_PIN_PEAK = 26, /* R 2 MFR_SPECIFIC_05 */
+ TI_LM25066A_MFR_CLEAR_PIN_PEAK = 27, /* W 0 MFR_SPECIFIC_06 */
+ TI_LM25066A_MFR_GATE_MASK = 28, /* RW 1 MFR_SPECIFIC_07 */
+ TI_LM25066A_MFR_ALERT_MASK = 29, /* RW 2 MFR_SPECIFIC_08 */
+ TI_LM25066A_MFR_DEVICE_SETUP = 30, /* RW 1 MFR_SPECIFIC_09 */
+ TI_LM25066A_MFR_BLOCK_READ = 31, /* R 12 MFR_SPECIFIC_10 */
+ TI_LM25066A_MFR_SAMPLES_FOR_AVG = 32, /* RW 1 MFR_SPECIFIC_11 */
+ TI_LM25066A_MFR_READ_AVG_VIN = 33, /* R 2 MFR_SPECIFIC_12 */
+ TI_LM25066A_MFR_READ_AVG_VOUT = 34, /* R 2 MFR_SPECIFIC_13 */
+ TI_LM25066A_MFR_READ_AVG_IIN = 35, /* R 2 MFR_SPECIFIC_14 */
+ TI_LM25066A_MFR_READ_AVG_PIN = 36, /* R 2 MFR_SPECIFIC_15 */
+ TI_LM25066A_MFR_BLACK_BOX_READ = 37, /* R 12 MFR_SPECIFIC_16 */
+ TI_LM25066A_MFR_DIAGNOSTIC_WORD_READ = 38, /* R 2 MFR_SPECIFIC_17 */
+ TI_LM25066A_MFR_AVG_BLOCK_READ = 39, /* R 12 MFR_SPECIFIC_18 */
+} ti_lm25066a_cmd;
+
+/*
+ * Real world converters. Page 46 of the datasheet discusses reading and
+ * writing telemtry data and obtaining the real world values. There are 8
+ * separate conversions using the same formula.
+ *
+ * The formula is:
+ *
+ * 1 -R
+ * X = - (Y x 10 - b)
+ * m
+ *
+ * X: the calculated "real world" value (volts, amps, watt, etc.)
+ * m: the slope coefficient
+ * Y: a two byte two's complement integer received from device
+ * b: the offset, a two byte two's complement integer
+ * R: the exponent, a one byte two's complement integer
+ *
+ * R in the table is inverted because we cannot store 0.01 in an int. This
+ * makes the equation:
+ *
+ * 1 Y
+ * X = - (- - b)
+ * m R
+ *
+ * The R value lets the integer result have decimal places.
+ *
+ * There are 8 conversion table entries listed in Table 41 of the
+ * data sheet. They are:
+ *
+ * 1. READ_VIN, READ_AVG_VIN, VIN_OV_WARN_LIMIT, VIN_UV_WARN_LIMIT
+ * 2. READ_VOUT, READ_AVG_VOUT, VOUT_UV_WARN_LIMIT
+ * 3. READ_VAUX
+ * 4.GND READ_IIN, READ_AVG_IIN, MFR_IIN_OC_WARN_LIMIT
+ * 4.VDD READ_IIN, READ_AVG_IIN, MFR_IIN_OC_WARN_LIMIT
+ * 5.GND READ_PIN, READ_AVG_PIN, READ_PIN_PEAK, MFR_PIN_OP_WARN_LIMIT
+ * 5.VCC READ_PIN, READ_AVG_PIN, READ_PIN_PEAK, MFR_PIN_OP_WARN_LIMIT
+ * 6. READ_TEMPERATURE_1, OT_WARN_LIMIT, OT_FAULT_LIMIT
+ *
+ * You need to provide 6 sets of conversion factors. Row 4 and 5 depend on how
+ * the device is wired. The driver will use the matching table row to convert
+ * the 2-complement 12 bit to a real world value.
+ */
+#define TI_LM25066A_CONVERSION_SIZE (6)
+typedef struct
+{
+ int m; /* The slope coefficient */
+ int b; /* The offset */
+ int R; /* The inverted power of 10 of -R */
+} ti_lm25066a_conversion;
+
+/*
+ * IO control interface.
+ */
+#define TI_LM25066A_GET (I2C_DEV_IO_CONTROL + 0)
+#define TI_LM25066A_SET (I2C_DEV_IO_CONTROL + 1)
+
+/*
+ * IO data types.
+ */
+typedef enum
+{
+ TI_LM25066A_8BIT = 0,
+ TI_LM25066A_16BIT = 1,
+ TI_LM25066A_VALUE = 2,
+ TI_LM25066A_VALUES = 3,
+ TI_LM25066A_STRING = 4,
+ TI_LM25066A_RAW = 5
+} ti_lm25066a_data;
+
+/*
+ * Struct to move data into and out of the driver.
+ */
+typedef struct
+{
+ ti_lm25066a_cmd cmd;
+ ti_lm25066a_data type;
+ union {
+ uint8_t u8;
+ uint16_t u16;
+ int value;
+ int values[6];
+ char string[9];
+ uint8_t* raw;
+ } data;
+} ti_lm25066a_io;
+
+/*
+ * Register the device.
+ *
+ * The conversions table has 6 columns.
+ *
+ * The values are an integer so the decimal_point value scales the value so it
+ * can fit in an integer with the required number of decimal points.
+ */
+int i2c_dev_register_ti_lm25066a(const char* bus_path,
+ const char* dev_path,
+ uint16_t address,
+ const ti_lm25066a_conversion* const conversions,
+ const int decimal_points);
+
+/*
+ * Get.
+ */
+static inline int
+ti_lm25066a_get(int fd, ti_lm25066a_io* io)
+{
+ return ioctl(fd, TI_LM25066A_GET, io);
+}
+
+/*
+ * Set.
+ */
+static inline int
+ti_lm25066a_set(int fd, ti_lm25066a_io* io)
+{
+ return ioctl(fd, TI_LM25066A_SET, io);
+}
+
+
+#endif
diff --git a/cpukit/dev/include/dev/i2c/ti-tmp112.h b/cpukit/dev/include/dev/i2c/ti-tmp112.h
new file mode 100644
index 0000000000..58efbef7d8
--- /dev/null
+++ b/cpukit/dev/include/dev/i2c/ti-tmp112.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * TI TMP112
+ * http://www.ti.com/product/TMP112
+ */
+
+#ifndef TI_TMP112_H
+#define TI_TMP112_H
+
+#include <dev/i2c/i2c.h>
+
+/*
+ * Confirguration.
+ */
+#define TI_TMP112_CR_0_25Hz (0 << 6)
+#define TI_TMP112_CR_1Hz (1 << 6)
+#define TI_TMP112_CR_4Hz (2 << 6) /* default */
+#define TI_TMP112_CR_8Hz (3 << 6)
+#define TI_TMP112_EM_NORMAL (0 << 4) /* default */
+#define TI_TMP112_EM_EXTENDED (1 << 4)
+#define TI_TMP112_SD_ON (0 << 8) /* default */
+#define TI_TMP112_SD_SHUTDOWN (1 << 8)
+#define TI_TMP112_TM_COMPARATOR (0 << 9) /* default */
+#define TI_TMP112_TM_INTERRUPT (1 << 9)
+#define TI_TMP112_POL_ALERT_LOW (0 << 10) /* default */
+#define TI_TMP112_POL_ALERT_HIGH (1 << 10)
+#define TI_TMP112_FQL_1 (0 << 11) /* default */
+#define TI_TMP112_FQL_2 (1 << 11)
+#define TI_TMP112_FQL_4 (2 << 11)
+#define TI_TMP112_FQL_6 (3 << 11)
+
+/*
+ * IO control interface.
+ */
+#define TI_TMP112_GET_TEMP (I2C_DEV_IO_CONTROL + 0)
+#define TI_TMP112_GET_TEMP_RAW (I2C_DEV_IO_CONTROL + 1)
+#define TI_TMP112_SET_CONFIG (I2C_DEV_IO_CONTROL + 2)
+#define TI_TMP112_SET_LOW_TEMP (I2C_DEV_IO_CONTROL + 3)
+#define TI_TMP112_SET_HIGH_TEMP (I2C_DEV_IO_CONTROL + 4)
+
+/*
+ * Register the device.
+ */
+int i2c_dev_register_ti_tmp112(const char* bus_path,
+ const char* dev_path,
+ uint16_t address);
+
+/*
+ * Get the temperature in degrees C x 10000. To print you would so:
+ *
+ * printf("Temperature is %3d.%04d\n", temp / 10000, temp % 10000);
+ *
+ * If the device is shutdown a single conversion is made waiting for the
+ * conversion to complete.
+ */
+static inline int
+ti_tmp112_get_temperature(int fd, int* temp)
+{
+ return ioctl(fd, TI_TMP112_GET_TEMP, temp);
+}
+
+/*
+ * Get the temperature as the raw register value.
+ *
+ * If the device is shutdown a single conversion is made waiting for the
+ * conversion to complete.
+ */
+static inline int
+ti_tmp112_get_temperature_raw(int fd, unsigned int* temp)
+{
+ return ioctl(fd, TI_TMP112_GET_TEMP_RAW, temp);
+}
+
+/*
+ * Set the configuration.
+ */
+static inline int
+ti_tmp112_adc_set_mux(int fd, uint16_t config)
+{
+ return ioctl(fd, TI_TMP112_SET_CONFIG, (void *)(uintptr_t) config);
+}
+
+/*
+ * Set the low temperature.
+ */
+static inline int
+ti_tmp112_set_low_temperator(int fd, uint16_t temp)
+{
+ return ioctl(fd, TI_TMP112_SET_LOW_TEMP, (void *)(uintptr_t) temp);
+}
+
+/*
+ * Set the high temperature.
+ */
+static inline int
+ti_tmp112_adc_set_high_threshold(int fd, uint16_t level)
+{
+ return ioctl(fd, TI_TMP112_SET_HIGH_TEMP, (void *)(uintptr_t) level);
+}
+
+#endif