2014-09-27 18:53:25 +02:00
|
|
|
/*
|
2015-09-21 17:31:55 +02:00
|
|
|
* Copyright (C) 2014-2015 Freie Universität Berlin
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
2015-09-21 17:31:55 +02:00
|
|
|
* 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.
|
2014-09-27 18:53:25 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2015-11-19 15:54:52 +01:00
|
|
|
* @defgroup drivers_periph_i2c I2C
|
|
|
|
* @ingroup drivers_periph
|
2014-09-27 18:53:25 +02:00
|
|
|
* @brief Low-level I2C peripheral driver
|
|
|
|
*
|
2014-12-04 10:03:15 +01:00
|
|
|
* @{
|
2014-09-27 18:53:25 +02:00
|
|
|
* @file
|
|
|
|
* @brief Low-level I2C peripheral driver interface definition
|
|
|
|
*
|
2015-09-21 17:31:55 +02:00
|
|
|
* 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}<br>
|
|
|
|
* where:<br>
|
|
|
|
* \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 <br>
|
|
|
|
* <br>The pull-up resistors depend on the bus speed.
|
|
|
|
* Some typical values are:<br>
|
|
|
|
* Normal mode: 10kΩ<br>
|
|
|
|
* Fast mode: 2kΩ<br>
|
|
|
|
* Fast plus mode: 2kΩ
|
|
|
|
*
|
|
|
|
* For more details refer to section 7.1 in:<br>
|
|
|
|
* http://www.nxp.com/documents/user_manual/UM10204.pdf
|
2014-12-16 10:54:31 +01:00
|
|
|
*
|
2014-12-16 15:17:42 +01:00
|
|
|
* @note The current version of this interface only supports the
|
2014-12-16 10:54:31 +01:00
|
|
|
7-bit addressing mode.
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
2015-01-19 10:55:12 +01:00
|
|
|
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
2014-09-27 18:53:25 +02:00
|
|
|
*/
|
|
|
|
|
2015-03-23 21:07:50 +01:00
|
|
|
#ifndef I2C_H
|
|
|
|
#define I2C_H
|
2014-09-27 18:53:25 +02:00
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2015-09-21 17:31:55 +02:00
|
|
|
#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"
|
2014-09-27 18:53:25 +02:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2015-09-21 17:31:55 +02:00
|
|
|
/**
|
|
|
|
* @brief Flag signaling a write operation on the bus
|
|
|
|
*/
|
2014-09-27 18:53:25 +02:00
|
|
|
#define I2C_FLAG_WRITE 0
|
2015-09-21 17:31:55 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Flag signaling a read operation on the bus
|
|
|
|
*/
|
2014-09-27 18:53:25 +02:00
|
|
|
#define I2C_FLAG_READ 1
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Default I2C device access macro
|
|
|
|
* @{
|
2014-09-27 18:53:25 +02:00
|
|
|
*/
|
2015-09-21 17:31:55 +02:00
|
|
|
#ifndef I2C_DEV
|
|
|
|
#define I2C_DEV(x) (x)
|
2014-09-27 18:53:25 +02:00
|
|
|
#endif
|
2015-09-21 17:31:55 +02:00
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Default I2C undefined value
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#ifndef I2C_UNDEF
|
|
|
|
#define I2C_UNDEF (-1)
|
2014-09-27 18:53:25 +02:00
|
|
|
#endif
|
2015-09-21 17:31:55 +02:00
|
|
|
/** @} */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Default i2c_t type definition
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#ifndef HAVE_I2C_T
|
|
|
|
typedef unsigned int i2c_t;
|
2014-09-27 18:53:25 +02:00
|
|
|
#endif
|
2015-09-21 17:31:55 +02:00
|
|
|
/** @} */
|
2014-09-27 18:53:25 +02:00
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Default mapping of I2C bus speed values
|
|
|
|
* @{
|
2014-09-27 18:53:25 +02:00
|
|
|
*/
|
2015-09-21 17:31:55 +02:00
|
|
|
#ifndef HAVE_I2C_SPEED_T
|
2014-09-27 18:53:25 +02:00
|
|
|
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;
|
2015-09-21 17:31:55 +02:00
|
|
|
#endif
|
|
|
|
/** @} */
|
2014-09-27 18:53:25 +02:00
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Initialize an I2C device to run as bus master
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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);
|
|
|
|
|
2015-01-19 10:55:12 +01:00
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Get mutually exclusive access to the given I2C bus
|
2015-01-19 10:55:12 +01:00
|
|
|
*
|
2015-09-21 17:31:55 +02:00
|
|
|
* In case the I2C device is busy, this function will block until the bus is
|
|
|
|
* free again.
|
2015-01-19 10:55:12 +01:00
|
|
|
*
|
|
|
|
* @param[in] dev I2C device to access
|
|
|
|
*
|
|
|
|
* @return 0 on success
|
|
|
|
* @return -1 on error
|
|
|
|
*/
|
|
|
|
int i2c_acquire(i2c_t dev);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Release the given I2C device to be used by others
|
2015-01-19 10:55:12 +01:00
|
|
|
*
|
|
|
|
* @param[in] dev I2C device to release
|
|
|
|
*
|
|
|
|
* @return 0 on success
|
|
|
|
* @return -1 on error
|
|
|
|
*/
|
|
|
|
int i2c_release(i2c_t dev);
|
|
|
|
|
2014-09-27 18:53:25 +02:00
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Read one byte from an I2C device with the given address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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, char *data);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Read multiple bytes from an I2C device with the given address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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, char *data, int length);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Read one byte from a register at the I2C slave with the given
|
|
|
|
* address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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, char *data);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Read multiple bytes from a register at the I2C slave with the given
|
|
|
|
* address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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
|
|
|
|
*/
|
2015-09-21 17:31:55 +02:00
|
|
|
int i2c_read_regs(i2c_t dev, uint8_t address, uint8_t reg,
|
|
|
|
char *data, int length);
|
2014-09-27 18:53:25 +02:00
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Write one byte to an I2C device with the given address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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, char data);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Write multiple bytes to an I2C device with the given address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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, char *data, int length);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Write one byte to a register at the I2C slave with the given address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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, char data);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Write multiple bytes to a register at the I2C slave with the given
|
|
|
|
* address
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @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
|
|
|
|
*/
|
2015-09-21 17:31:55 +02:00
|
|
|
int i2c_write_regs(i2c_t dev, uint8_t address, uint8_t reg,
|
|
|
|
char *data, int length);
|
2014-09-27 18:53:25 +02:00
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Power on the given I2C peripheral
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @param[in] dev the I2C device to power on
|
|
|
|
*/
|
|
|
|
void i2c_poweron(i2c_t dev);
|
|
|
|
|
|
|
|
/**
|
2015-09-21 17:31:55 +02:00
|
|
|
* @brief Power off the given I2C peripheral
|
2014-09-27 18:53:25 +02:00
|
|
|
*
|
|
|
|
* @param[in] dev the I2C device to power off
|
|
|
|
*/
|
|
|
|
void i2c_poweroff(i2c_t dev);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-03-23 21:07:50 +01:00
|
|
|
#endif /* I2C_H */
|
2014-09-27 18:53:25 +02:00
|
|
|
/** @} */
|