/* * Copyright (C) 2014-2015 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @defgroup drivers_periph_i2c I2C * @ingroup drivers_periph * @brief Low-level I2C peripheral driver * * This is a simple I2C interface to allow platform independent access to a * MCU's I2C bus and peripherals. This interface is intentionally designed as * simple as possible, to allow for easy implementation and maximal portability. * * @note The current version of this interface only supports the * 7-bit addressing mode. * * @note This interface is due for remodeling, hence API changes are to * be expected for upcoming releases. * * ## A note on pull-up resistors for SDA/SCL * * The I2C signal lines SDA/SCL need external pull-up resistors which connect * the lines to the positive voltage supply VCC. The I2C driver implementation * should enable the pin's internal pull-up resistors. There are however some * use cases for which the internal pull resistors are not strong enough and the * I2C bus will show faulty behavior. This can for example happen when * connecting a logic analyzer which will raise the capacitance of the bus. In * this case you should make sure you connect external pull-up resistors to both * I2C bus lines. * * The minimum and maximum resistances are computed by: * \f{eqnarray*}{ * R_{min} &=& \frac{V_{DD} - V_{OL(max)}} {I_{OL}}\\ * R_{max} &=& \frac{t_r} {(0.8473 \cdot C_b)} * \f}
* where:
* \f$ V_{DD} =\f$ Supply voltage, * \f$ V_{OL(max)} =\f$ Low level voltage, * \f$ I_{OL} =\f$ Low level output current, * \f$ t_r =\f$ Signal rise time, * \f$ C_b =\f$ Bus capacitance
*
The pull-up resistors depend on the bus speed. * Some typical values are:
* Normal mode: 10kΩ
* Fast mode: 2kΩ
* Fast plus mode: 2kΩ * * For more details refer to section 7.1 in:
* http://www.nxp.com/documents/user_manual/UM10204.pdf * * @{ * @file * @brief Low-level I2C peripheral driver interface definition * * @author Hauke Petersen * @author Thomas Eichinger */ #ifndef PERIPH_I2C_H #define PERIPH_I2C_H #include #include #include "periph_cpu.h" /** * @todo Remove dev_enums.h include once all platforms are ported to the * updated periph interface */ #include "periph/dev_enums.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Flag signaling a write operation on the bus */ #define I2C_FLAG_WRITE 0 /** * @brief Flag signaling a read operation on the bus */ #define I2C_FLAG_READ 1 /** * @brief Default I2C device access macro */ #ifndef I2C_DEV #define I2C_DEV(x) (x) #endif /** * @brief Default I2C undefined value */ #ifndef I2C_UNDEF #define I2C_UNDEF (UINT_MAX) #endif /** * @brief Default i2c_t type definition */ #ifndef HAVE_I2C_T typedef unsigned int i2c_t; #endif /** * @brief Default mapping of I2C bus speed values */ #ifndef HAVE_I2C_SPEED_T typedef enum { I2C_SPEED_LOW = 0, /**< low speed mode: ~10kbit/s */ I2C_SPEED_NORMAL, /**< normal mode: ~100kbit/s */ I2C_SPEED_FAST, /**< fast mode: ~400kbit/sj */ I2C_SPEED_FAST_PLUS, /**< fast plus mode: ~1Mbit/s */ I2C_SPEED_HIGH, /**< high speed mode: ~3.4Mbit/s */ } i2c_speed_t; #endif /** * @brief Initialize an I2C device to run as bus master * * @param[in] dev the device to initialize * @param[in] speed the selected bus speed * * @return 0 on successful initialization * @return -1 on undefined device given * @return -2 on unsupported speed value */ int i2c_init_master(i2c_t dev, i2c_speed_t speed); /** * @brief Get mutually exclusive access to the given I2C bus * * In case the I2C device is busy, this function will block until the bus is * free again. * * @param[in] dev I2C device to access * * @return 0 on success * @return -1 on error */ int i2c_acquire(i2c_t dev); /** * @brief Release the given I2C device to be used by others * * @param[in] dev I2C device to release * * @return 0 on success * @return -1 on error */ int i2c_release(i2c_t dev); /** * @brief Read one byte from an I2C device with the given address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[out] data the result that was read * * @return the number of bytes that were read * @return -1 on undefined device given * @return -2 on invalid address */ int i2c_read_byte(i2c_t dev, uint8_t address, void *data); /** * @brief Read multiple bytes from an I2C device with the given address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[out] data array holding the received bytes * @param[in] length the number of bytes to read into `data` * * @return the number of bytes that were read * @return -1 on undefined device given */ int i2c_read_bytes(i2c_t dev, uint8_t address, void *data, int length); /** * @brief Read one byte from a register at the I2C slave with the given * address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[in] reg the register address on the targeted I2C device * @param[out] data the result that was read * * @return the number of bytes that were read * @return -1 on undefined device given */ int i2c_read_reg(i2c_t dev, uint8_t address, uint8_t reg, void *data); /** * @brief Read multiple bytes from a register at the I2C slave with the given * address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[in] reg the register address on the targeted I2C device * @param[out] data array holding the received bytes * @param[in] length the number of bytes to read into `data` * * @return the number of bytes that were read * @return -1 on undefined device given */ int i2c_read_regs(i2c_t dev, uint8_t address, uint8_t reg, void *data, int length); /** * @brief Write one byte to an I2C device with the given address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[in] data byte to write to the device * * @return the number of bytes that were written * @return -1 on undefined device given */ int i2c_write_byte(i2c_t dev, uint8_t address, uint8_t data); /** * @brief Write multiple bytes to an I2C device with the given address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[in] data array with bytes to write to the target device * @param[in] length number of bytes to write to the target device * * @return the number of bytes that were written * @return -1 on undefined device given */ int i2c_write_bytes(i2c_t dev, uint8_t address, const void *data, int length); /** * @brief Write one byte to a register at the I2C slave with the given address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[in] reg the register address on the targeted I2C device * @param[in] data byte to write to the device * * @return the number of bytes that were written * @return -1 on undefined device given */ int i2c_write_reg(i2c_t dev, uint8_t address, uint8_t reg, uint8_t data); /** * @brief Write multiple bytes to a register at the I2C slave with the given * address * * @param[in] dev I2C peripheral device * @param[in] address bus address of the target device * @param[in] reg the register address on the targeted I2C device * @param[in] data array with bytes to write to the target device * @param[in] length number of bytes to write to the target device * * @return the number of bytes that were written * @return -1 on undefined device given */ int i2c_write_regs(i2c_t dev, uint8_t address, uint8_t reg, const void *data, int length); /** * @brief Power on the given I2C peripheral * * @param[in] dev the I2C device to power on */ void i2c_poweron(i2c_t dev); /** * @brief Power off the given I2C peripheral * * @param[in] dev the I2C device to power off */ void i2c_poweroff(i2c_t dev); #ifdef __cplusplus } #endif #endif /* PERIPH_I2C_H */ /** @} */