diff options
Diffstat (limited to 'cpukit/include/dev/i2c')
-rw-r--r-- | cpukit/include/dev/i2c/eeprom.h | 58 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/fpga-i2c-slave.h | 25 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/gpio-nxp-pca9535.h | 123 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/i2c.h | 432 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/sensor-lm75a.h | 125 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/switch-nxp-pca9548a.h | 68 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/ti-ads-16bit-adc.h | 203 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/ti-lm25066a.h | 190 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/ti-tmp112.h | 109 | ||||
-rw-r--r-- | cpukit/include/dev/i2c/xilinx-axi-i2c.h | 86 |
10 files changed, 1419 insertions, 0 deletions
diff --git a/cpukit/include/dev/i2c/eeprom.h b/cpukit/include/dev/i2c/eeprom.h new file mode 100644 index 0000000000..73df5ad9f4 --- /dev/null +++ b/cpukit/include/dev/i2c/eeprom.h @@ -0,0 +1,58 @@ +/** + * @file + * + * @brief EEPROM Driver API + * + * @ingroup I2CEEPROM + */ + +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@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_EEPROM_H +#define _DEV_I2C_EEPROM_H + +#include <dev/i2c/i2c.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup I2CEEPROM EEPROM Driver + * + * @ingroup I2CDevice + * + * @brief Driver for EEPROM device. + * + * @{ + */ + +int i2c_dev_register_eeprom( + const char *bus_path, + const char *dev_path, + uint16_t i2c_address, + uint16_t address_bytes, + uint16_t page_size_in_bytes, + uint32_t size_in_bytes, + uint32_t program_timeout_in_ms +); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_I2C_EEPROM_H */ diff --git a/cpukit/include/dev/i2c/fpga-i2c-slave.h b/cpukit/include/dev/i2c/fpga-i2c-slave.h new file mode 100644 index 0000000000..c10b26ac5b --- /dev/null +++ b/cpukit/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/include/dev/i2c/gpio-nxp-pca9535.h b/cpukit/include/dev/i2c/gpio-nxp-pca9535.h new file mode 100644 index 0000000000..1ebc1a3d4d --- /dev/null +++ b/cpukit/include/dev/i2c/gpio-nxp-pca9535.h @@ -0,0 +1,123 @@ +/** + * @file + * + * @brief GPIO NXP PCA9535 Driver API + * + * @ingroup I2CGPIONXPPCA9535 + */ + +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@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_GPIO_NXP_PCA9539_H +#define _DEV_I2C_GPIO_NXP_PCA9539_H + +#include <dev/i2c/i2c.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup I2CGPIONXPPCA9535 GPIO NXP PCA9535 Driver + * + * @ingroup I2CDevice + * + * @brief Driver for NXP PCA9535 16-bit GPIO device. + * + * @{ + */ + +int i2c_dev_register_gpio_nxp_pca9535( + const char *bus_path, + const char *dev_path, + uint16_t address +); + +#define GPIO_NXP_PCA9535_GET_INPUT (I2C_DEV_IO_CONTROL + 0) + +#define GPIO_NXP_PCA9535_GET_OUTPUT (I2C_DEV_IO_CONTROL + 1) + +#define GPIO_NXP_PCA9535_SET_OUTPUT (I2C_DEV_IO_CONTROL + 2) + +#define GPIO_NXP_PCA9535_CLEAR_AND_SET_OUTPUT (I2C_DEV_IO_CONTROL + 3) + +#define GPIO_NXP_PCA9535_GET_POL_INV (I2C_DEV_IO_CONTROL + 4) + +#define GPIO_NXP_PCA9535_SET_POL_INV (I2C_DEV_IO_CONTROL + 5) + +#define GPIO_NXP_PCA9535_GET_CONFIG (I2C_DEV_IO_CONTROL + 6) + +#define GPIO_NXP_PCA9535_SET_CONFIG (I2C_DEV_IO_CONTROL + 7) + +static inline int gpio_nxp_pca9535_get_input(int fd, uint16_t *val) +{ + return ioctl(fd, GPIO_NXP_PCA9535_GET_INPUT, val); +} + +static inline int gpio_nxp_pca9535_get_output(int fd, uint16_t *val) +{ + return ioctl(fd, GPIO_NXP_PCA9535_GET_OUTPUT, val); +} + +static inline int gpio_nxp_pca9535_set_output(int fd, uint16_t val) +{ + return ioctl(fd, GPIO_NXP_PCA9535_SET_OUTPUT, (void *)(uintptr_t) val); +} + +static inline int gpio_nxp_pca9535_clear_and_set_output( + int fd, + uint16_t clear, + uint16_t set +) +{ + uint32_t clear_and_set = ((uint32_t) set << 16) | (uint32_t) clear; + + return ioctl( + fd, + GPIO_NXP_PCA9535_CLEAR_AND_SET_OUTPUT, + (void *)(uintptr_t) clear_and_set + ); +} + +static inline int gpio_nxp_pca9535_get_polarity_inversion( + int fd, + uint16_t *val +) +{ + return ioctl(fd, GPIO_NXP_PCA9535_GET_POL_INV, val); +} + +static inline int gpio_nxp_pca9535_set_polarity_inversion(int fd, uint16_t val) +{ + return ioctl(fd, GPIO_NXP_PCA9535_SET_POL_INV, (void *)(uintptr_t) val); +} + +static inline int gpio_nxp_pca9535_get_config(int fd, uint16_t *val) +{ + return ioctl(fd, GPIO_NXP_PCA9535_GET_CONFIG, val); +} + +static inline int gpio_nxp_pca9535_set_config(int fd, uint16_t val) +{ + return ioctl(fd, GPIO_NXP_PCA9535_SET_CONFIG, (void *)(uintptr_t) val); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_I2C_GPIO_NXP_PCA9539_H */ diff --git a/cpukit/include/dev/i2c/i2c.h b/cpukit/include/dev/i2c/i2c.h new file mode 100644 index 0000000000..2ace4fcf64 --- /dev/null +++ b/cpukit/include/dev/i2c/i2c.h @@ -0,0 +1,432 @@ +/** + * @file + * + * @brief Inter-Integrated Circuit (I2C) Driver API + * + * @ingroup I2C + */ + +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@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_I2C_H +#define _DEV_I2C_I2C_H + +#include <linux/i2c.h> +#include <linux/i2c-dev.h> + +#include <rtems.h> +#include <rtems/seterr.h> + +#include <sys/ioctl.h> +#include <sys/stat.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct i2c_msg i2c_msg; + +typedef struct i2c_bus i2c_bus; + +typedef struct i2c_dev i2c_dev; + +typedef struct i2c_rdwr_ioctl_data i2c_rdwr_ioctl_data; + +/** + * @defgroup I2C Inter-Integrated Circuit (I2C) Driver + * + * @brief Inter-Integrated Circuit (I2C) bus and device driver support. + * + * @{ + */ + +/** + * @defgroup I2CBus I2C Bus Driver + * + * @ingroup I2C + * + * @{ + */ + +/** + * @name I2C IO Control Commands + * + * @{ + */ + +/** + * @brief Obtains the bus. + * + * This command has no argument. + */ +#define I2C_BUS_OBTAIN 0x800 + +/** + * @brief Releases the bus. + * + * This command has no argument. + */ +#define I2C_BUS_RELEASE 0x801 + +/** + * @brief Gets the bus control. + * + * The argument type is a pointer to i2c_bus pointer. + */ +#define I2C_BUS_GET_CONTROL 0x802 + +/** + * @brief Sets the bus clock in Hz. + * + * The argument type is unsigned long. + */ +#define I2C_BUS_SET_CLOCK 0x803 + +/** @} */ + +/** + * @brief Default I2C bus clock in Hz. + */ +#define I2C_BUS_CLOCK_DEFAULT 100000 + +/** + * @brief I2C bus control. + */ +struct i2c_bus { + /** + * @brief Transfers I2C messages. + * + * @param[in] bus The bus control. + * @param[in] msgs The messages to transfer. + * @param[in] msg_count The count of messages to transfer. It must be + * positive. + * + * @retval 0 Successful operation. + * @retval negative Negative error number in case of an error. + */ + int (*transfer)(i2c_bus *bus, i2c_msg *msgs, uint32_t msg_count); + + /** + * @brief Sets the bus clock. + * + * @param[in] bus The bus control. + * @param[in] clock The desired bus clock in Hz. + * + * @retval 0 Successful operation. + * @retval negative Negative error number in case of an error. + */ + int (*set_clock)(i2c_bus *bus, unsigned long clock); + + /** + * @brief Destroys the bus. + * + * @param[in] bus The bus control. + */ + void (*destroy)(i2c_bus *bus); + + /** + * @brief Mutex to protect the bus access. + */ + rtems_id mutex; + + /** + * @brief Default slave device address. + */ + uint16_t default_address; + + /** + * @brief Use 10-bit addresses. + */ + bool ten_bit_address; + + /** + * @brief Use SMBus PEC. + */ + bool use_pec; + + /** + * @brief Transfer retry count. + */ + unsigned long retries; + + /** + * @brief Transaction timeout in ticks. + */ + rtems_interval timeout; + + /** + * @brief Controller functionality. + */ + unsigned long functionality; +}; + +/** + * @brief Initializes a bus control. + * + * After a sucessful initialization the bus control must be destroyed via + * i2c_bus_destroy(). A registered bus control will be automatically destroyed + * in case the device file is unlinked. Make sure to call i2c_bus_destroy() in + * a custom destruction handler. + * + * @param[in] bus The bus control. + * + * @retval 0 Successful operation. + * @retval -1 An error occurred. The errno is set to indicate the error. + * + * @see i2c_bus_register() + */ +int i2c_bus_init(i2c_bus *bus); + +/** + * @brief Allocates a bus control from the heap and initializes it. + * + * After a sucessful allocation and initialization the bus control must be + * destroyed via i2c_bus_destroy_and_free(). A registered bus control will be + * automatically destroyed in case the device file is unlinked. Make sure to + * call i2c_bus_destroy_and_free() in a custom destruction handler. + * + * @param[in] size The size of the bus control. This enables the addition of + * bus controller specific data to the base bus control. The bus control is + * zero initialized. + * + * @retval non-NULL The new bus control. + * @retval NULL An error occurred. The errno is set to indicate the error. + * + * @see i2c_bus_register() + */ +i2c_bus *i2c_bus_alloc_and_init(size_t size); + +/** + * @brief Destroys a bus control. + * + * @param[in] bus The bus control. + */ +void i2c_bus_destroy(i2c_bus *bus); + +/** + * @brief Destroys a bus control and frees its memory. + * + * @param[in] bus The bus control. + */ +void i2c_bus_destroy_and_free(i2c_bus *bus); + +/** + * @brief Registers a bus control. + * + * This function claims ownership of the bus control regardless if the + * registration is successful or not. + * + * @param[in] bus The bus control. + * @param[in] bus_path The path to the bus device file. + * + * @retval 0 Successful operation. + * @retval -1 An error occurred. The errno is set to indicate the error. + */ +int i2c_bus_register( + i2c_bus *bus, + const char *bus_path +); + +/** + * @brief Obtains the bus. + * + * @param[in] bus The bus control. + */ +void i2c_bus_obtain(i2c_bus *bus); + +/** + * @brief Releases the bus. + * + * @param[in] bus The bus control. + */ +void i2c_bus_release(i2c_bus *bus); + +/** + * @brief Transfers I2C messages. + * + * The bus is obtained before the transfer and released afterwards. + * + * @param[in] bus The bus control. + * @param[in] msgs The messages to transfer. + * @param[in] msg_count The count of messages to transfer. It must be + * positive. + * + * @retval 0 Successful operation. + * @retval negative Negative error number in case of an error. + */ +int i2c_bus_transfer(i2c_bus *bus, i2c_msg *msgs, uint32_t msg_count); + +/** @} */ + +/** + * @defgroup I2CDevice I2C Device Driver + * + * @ingroup I2C + * + * @{ + */ + +/** + * @brief Base number for device IO control commands. + */ +#define I2C_DEV_IO_CONTROL 0x900 + +/** + * @brief I2C slave device control. + */ +struct i2c_dev { + /** + * @brief Reads from the device. + * + * @retval non-negative Bytes transferred from device. + * @retval negative Negative error number in case of an error. + */ + ssize_t (*read)(i2c_dev *dev, void *buf, size_t n, off_t offset); + + /** + * @brief Writes to the device. + * + * @retval non-negative Bytes transferred to device. + * @retval negative Negative error number in case of an error. + */ + ssize_t (*write)(i2c_dev *dev, const void *buf, size_t n, off_t offset); + + /** + * @brief Device IO control. + * + * @retval 0 Successful operation. + * @retval negative Negative error number in case of an error. + */ + int (*ioctl)(i2c_dev *dev, ioctl_command_t command, void *arg); + + /** + * @brief Gets the file size. + */ + off_t (*get_size)(i2c_dev *dev); + + /** + * @brief Gets the file block size. + */ + blksize_t (*get_block_size)(i2c_dev *dev); + + /** + * @brief Destroys the device. + */ + void (*destroy)(i2c_dev *dev); + + /** + * @brief The bus control. + */ + i2c_bus *bus; + + /** + * @brief The device address. + */ + uint16_t address; + + /** + * @brief File descriptor of the bus. + * + * This prevents destruction of the bus since we hold a reference to it with + * this. + */ + int bus_fd; +}; + + +/** + * @brief Initializes a device control. + * + * After a sucessful initialization the device control must be destroyed via + * i2c_dev_destroy(). A registered device control will be automatically + * destroyed in case the device file is unlinked. Make sure to call + * i2c_dev_destroy_and_free() in a custom destruction handler. + * + * @param[in] device The device control. + * @param[in] bus_path The path to the bus device file. + * @param[in] address The address of the device. + * + * @retval 0 Successful operation. + * @retval -1 An error occurred. The errno is set to indicate the error. + * + * @see i2c_dev_register() + */ +int i2c_dev_init(i2c_dev *dev, const char *bus_path, uint16_t address); + +/** + * @brief Allocates a device control from the heap and initializes it. + * + * After a sucessful allocation and initialization the device control must be + * destroyed via i2c_dev_destroy_and_free(). A registered device control will + * be automatically destroyed in case the device file is unlinked. Make sure + * to call i2c_dev_destroy_and_free() in a custom destruction handler. + * + * @param[in] size The size of the device control. This enables the addition + * of device specific data to the base device control. The device control is + * zero initialized. + * @param[in] bus_path The path to the bus device file. + * @param[in] address The address of the device. + * + * @retval non-NULL The new device control. + * @retval NULL An error occurred. The errno is set to indicate the error. + * + * @see i2c_dev_register() + */ +i2c_dev *i2c_dev_alloc_and_init( + size_t size, + const char *bus_path, + uint16_t address +); + +/** + * @brief Destroys a device control. + * + * @param[in] dev The device control. + */ +void i2c_dev_destroy(i2c_dev *dev); + +/** + * @brief Destroys a device control and frees its memory. + * + * @param[in] dev The device control. + */ +void i2c_dev_destroy_and_free(i2c_dev *dev); + +/** + * @brief Registers a device control. + * + * This function claims ownership of the device control regardless if the + * registration is successful or not. + * + * @param[in] dev The dev control. + * @param[in] dev_path The path to the device file of the device. + * + * @retval 0 Successful operation. + * @retval -1 An error occurred. The errno is set to indicate the error. + */ +int i2c_dev_register( + i2c_dev *dev, + const char *dev_path +); + +/** @} */ /* end of i2c device driver */ + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_I2C_I2C_H */ diff --git a/cpukit/include/dev/i2c/sensor-lm75a.h b/cpukit/include/dev/i2c/sensor-lm75a.h new file mode 100644 index 0000000000..e1957dad19 --- /dev/null +++ b/cpukit/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@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/include/dev/i2c/switch-nxp-pca9548a.h b/cpukit/include/dev/i2c/switch-nxp-pca9548a.h new file mode 100644 index 0000000000..ce8ef2c809 --- /dev/null +++ b/cpukit/include/dev/i2c/switch-nxp-pca9548a.h @@ -0,0 +1,68 @@ +/** + * @file + * + * @brief Switch NXP PCA9548A Driver API + * + * @ingroup I2CSWITCHNXPPCA9548A + */ + +/* + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@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_SWITCH_NXP_PCA9548A_H +#define _DEV_I2C_SWITCH_NXP_PCA9548A_H + +#include <dev/i2c/i2c.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup I2CSWITCHNXPPCA9548A Switch NXP PCA9535 Driver + * + * @ingroup I2CDevice + * + * @brief Driver for NXP PCA9548A 8-channel switch device. + * + * @{ + */ + +int i2c_dev_register_switch_nxp_pca9548a( + const char *bus_path, + const char *dev_path, + uint16_t address +); + +#define SWITCH_NXP_PCA9548A_GET_CONTROL (I2C_DEV_IO_CONTROL + 0) + +#define SWITCH_NXP_PCA9548A_SET_CONTROL (I2C_DEV_IO_CONTROL + 1) + +static inline int switch_nxp_pca9548a_get_control(int fd, uint8_t *val) +{ + return ioctl(fd, SWITCH_NXP_PCA9548A_GET_CONTROL, val); +} + +static inline int switch_nxp_pca9548a_set_control(int fd, uint8_t val) +{ + return ioctl(fd, SWITCH_NXP_PCA9548A_SET_CONTROL, (void *)(uintptr_t) val); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_I2C_SWITCH_NXP_PCA9548A_H */ diff --git a/cpukit/include/dev/i2c/ti-ads-16bit-adc.h b/cpukit/include/dev/i2c/ti-ads-16bit-adc.h new file mode 100644 index 0000000000..40d680da88 --- /dev/null +++ b/cpukit/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/include/dev/i2c/ti-lm25066a.h b/cpukit/include/dev/i2c/ti-lm25066a.h new file mode 100644 index 0000000000..4429f0fc70 --- /dev/null +++ b/cpukit/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/include/dev/i2c/ti-tmp112.h b/cpukit/include/dev/i2c/ti-tmp112.h new file mode 100644 index 0000000000..1b80fa6994 --- /dev/null +++ b/cpukit/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_config(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 diff --git a/cpukit/include/dev/i2c/xilinx-axi-i2c.h b/cpukit/include/dev/i2c/xilinx-axi-i2c.h new file mode 100644 index 0000000000..fafac346ec --- /dev/null +++ b/cpukit/include/dev/i2c/xilinx-axi-i2c.h @@ -0,0 +1,86 @@ +/* + * 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. + */ + +/* + * Xilinx AXI IIC Interface v2.0. See PG090.pdf. + * + * Note, only master support is provided and no dynamic mode by design. + * + * The clock set up is to be handled by the IP integrator. There are too many + * factors handling this in software. + */ + + +#ifndef XILINX_AXI_I2C_H +#define XILINX_AXI_I2C_H + +#include <dev/i2c/i2c.h> + +/* + * The PL integrator controls the timing. This interface allows software to + * override those settings. It pays to check the timing with ChipScope. + * + * If you set the AXI bus frequency you can use the clock speed ioctl call to + * change the speed dymanically. The ioctl call overrides the defaults passed + * in. + * + * Set the valid mask to the values that are to be set. + */ +#define XILINX_AIX_I2C_AXI_CLOCK (1 << 0) +#define XILINX_AIX_I2C_TSUSTA (1 << 1) +#define XILINX_AIX_I2C_TSUSTO (1 << 2) +#define XILINX_AIX_I2C_THDSTA (1 << 3) +#define XILINX_AIX_I2C_TSUDAT (1 << 4) +#define XILINX_AIX_I2C_TBUF (1 << 5) +#define XILINX_AIX_I2C_THIGH (1 << 6) +#define XILINX_AIX_I2C_TLOW (1 << 7) +#define XILINX_AIX_I2C_THDDAT (1 << 8) +#define XILINX_AIX_I2C_ALL_REGS (XILINX_AIX_I2C_TSUSTA | \ + XILINX_AIX_I2C_TSUSTO | \ + XILINX_AIX_I2C_THDSTA | \ + XILINX_AIX_I2C_TSUDAT | \ + XILINX_AIX_I2C_TBUF | \ + XILINX_AIX_I2C_THIGH | \ + XILINX_AIX_I2C_TLOW | \ + XILINX_AIX_I2C_THDDAT) +typedef struct +{ + uint32_t valid_mask; + uint32_t AXI_CLOCK; + uint32_t SCL_INERTIAL_DELAY; + uint32_t TSUSTA; + uint32_t TSUSTO; + uint32_t THDSTA; + uint32_t TSUDAT; + uint32_t TBUF; + uint32_t THIGH; + uint32_t TLOW; + uint32_t THDDAT; +} xilinx_aix_i2c_timing; + +/* + * Register the driver. + * + * The driver can multipex a number of I2C buses (in master mode only) using + * the GPO port. The PL designer can use the output pins to select a bus. This + * is useful if connecting a number of slave devices that have limit selectable + * addresses. + * + * @param bus_path The driver's device path. + * @param register_base AXI base address. + * @param irq AXI FPGA interrupt. + * @param gpio_address Bits 12:15 of a slave address it written to the GPO. + * @param timing Override the default timing. NULL means no changes. + */ +int i2c_bus_register_xilinx_aix_i2c(const char* bus_path, + uintptr_t register_base, + rtems_vector_number irq, + bool ten_gpio, + const xilinx_aix_i2c_timing* timing); + +#endif |