2018-05-23 15:59:02 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2018 Mesotic SAS <dylan.laduranty@mesotic.com>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2018-05-23 18:06:05 +02:00
|
|
|
* @ingroup drivers_periph_i2c
|
2018-05-23 15:59:02 +02:00
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @brief common I2C function fallback implementations
|
|
|
|
*
|
|
|
|
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
|
|
|
*
|
|
|
|
* @}
|
|
|
|
*/
|
2018-12-10 09:49:18 +01:00
|
|
|
#include <errno.h>
|
2018-05-23 15:59:02 +02:00
|
|
|
|
|
|
|
#include "board.h"
|
|
|
|
#include "cpu.h"
|
|
|
|
#include "periph/i2c.h"
|
2019-05-22 07:33:12 +02:00
|
|
|
#include "byteorder.h"
|
2018-05-23 15:59:02 +02:00
|
|
|
|
2018-05-25 11:55:27 +02:00
|
|
|
#ifdef PERIPH_I2C_NEED_READ_REG
|
2018-05-24 10:36:29 +02:00
|
|
|
int i2c_read_reg(i2c_t dev, uint16_t addr, uint16_t reg,
|
2018-05-23 15:59:02 +02:00
|
|
|
void *data, uint8_t flags)
|
|
|
|
{
|
2018-05-23 18:06:05 +02:00
|
|
|
return i2c_read_regs(dev, addr, reg, data, 1, flags);
|
2018-05-23 15:59:02 +02:00
|
|
|
}
|
2018-05-25 11:55:27 +02:00
|
|
|
#endif /* PERIPH_I2C_NEED_READ_REG */
|
2018-05-23 15:59:02 +02:00
|
|
|
|
2018-05-25 11:55:27 +02:00
|
|
|
#ifdef PERIPH_I2C_NEED_READ_REGS
|
2018-05-24 10:36:29 +02:00
|
|
|
int i2c_read_regs(i2c_t dev, uint16_t addr, uint16_t reg,
|
2018-05-23 18:06:05 +02:00
|
|
|
void *data, size_t len, uint8_t flags)
|
2018-05-23 15:59:02 +02:00
|
|
|
{
|
2019-05-22 07:33:12 +02:00
|
|
|
uint16_t reg_end = reg;
|
|
|
|
|
2018-12-10 09:49:18 +01:00
|
|
|
if (flags & (I2C_NOSTOP | I2C_NOSTART)) {
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
2019-05-22 07:33:12 +02:00
|
|
|
|
2019-09-14 15:47:10 +02:00
|
|
|
/* Handle endianness of register if 16 bit */
|
2019-05-22 07:33:12 +02:00
|
|
|
if (flags & I2C_REG16) {
|
|
|
|
reg_end = htons(reg); /* Make sure register is in big-endian on I2C bus */
|
|
|
|
}
|
|
|
|
|
2018-05-23 18:06:05 +02:00
|
|
|
/* First set ADDR and register with no stop */
|
2019-05-22 07:33:12 +02:00
|
|
|
int ret = i2c_write_bytes(dev, addr, ®_end, (flags & I2C_REG16) ? 2 : 1,
|
2018-06-02 21:07:30 +02:00
|
|
|
flags | I2C_NOSTOP);
|
2018-05-25 11:55:27 +02:00
|
|
|
if (ret < 0) {
|
|
|
|
return ret;
|
2018-05-23 18:06:05 +02:00
|
|
|
}
|
|
|
|
/* Then get the data from device */
|
|
|
|
return i2c_read_bytes(dev, addr, data, len, flags);
|
2018-05-23 15:59:02 +02:00
|
|
|
}
|
|
|
|
#endif /* PERIPH_I2C_NEED_READ_REGS */
|
|
|
|
|
2018-05-24 10:36:29 +02:00
|
|
|
int i2c_read_byte(i2c_t dev, uint16_t addr, void *data, uint8_t flags)
|
2018-05-23 15:59:02 +02:00
|
|
|
{
|
2018-05-23 18:06:05 +02:00
|
|
|
return i2c_read_bytes(dev, addr, data, 1, flags);
|
2018-05-23 15:59:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int i2c_write_byte(i2c_t dev, uint16_t addr, uint8_t data, uint8_t flags)
|
|
|
|
{
|
2018-05-24 10:36:29 +02:00
|
|
|
return i2c_write_bytes(dev, addr, &data, 1, flags);
|
2018-05-23 15:59:02 +02:00
|
|
|
}
|
|
|
|
|
2018-05-25 11:55:27 +02:00
|
|
|
#ifdef PERIPH_I2C_NEED_WRITE_REG
|
2018-05-23 15:59:02 +02:00
|
|
|
int i2c_write_reg(i2c_t dev, uint16_t addr, uint16_t reg,
|
2018-05-24 11:35:35 +02:00
|
|
|
uint8_t data, uint8_t flags)
|
2018-05-23 15:59:02 +02:00
|
|
|
{
|
2018-05-24 11:35:35 +02:00
|
|
|
return i2c_write_regs(dev, addr, reg, &data, 1, flags);
|
2018-05-23 15:59:02 +02:00
|
|
|
}
|
2018-05-25 11:55:27 +02:00
|
|
|
#endif /* PERIPH_I2C_NEED_WRITE_REG */
|
2018-05-23 15:59:02 +02:00
|
|
|
|
2018-05-25 11:55:27 +02:00
|
|
|
#ifdef PERIPH_I2C_NEED_WRITE_REGS
|
2018-05-23 15:59:02 +02:00
|
|
|
int i2c_write_regs(i2c_t dev, uint16_t addr, uint16_t reg,
|
2018-05-23 18:06:05 +02:00
|
|
|
const void *data, size_t len, uint8_t flags)
|
2018-05-23 15:59:02 +02:00
|
|
|
{
|
2019-05-22 07:33:12 +02:00
|
|
|
uint16_t reg_end = reg;
|
|
|
|
|
2018-12-10 09:49:18 +01:00
|
|
|
if (flags & (I2C_NOSTOP | I2C_NOSTART)) {
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
2019-05-22 07:33:12 +02:00
|
|
|
|
2019-09-14 15:47:10 +02:00
|
|
|
/* Handle endianness of register if 16 bit */
|
2019-05-22 07:33:12 +02:00
|
|
|
if (flags & I2C_REG16) {
|
|
|
|
reg_end = htons(reg); /* Make sure register is in big-endian on I2C bus */
|
|
|
|
}
|
|
|
|
|
2018-05-23 18:06:05 +02:00
|
|
|
/* First set ADDR and register with no stop */
|
2019-05-22 07:33:12 +02:00
|
|
|
int ret = i2c_write_bytes(dev, addr, ®_end, (flags & I2C_REG16) ? 2 : 1,
|
2018-06-02 21:07:30 +02:00
|
|
|
flags | I2C_NOSTOP);
|
2018-05-25 11:55:27 +02:00
|
|
|
if (ret < 0) {
|
|
|
|
return ret;
|
2018-05-23 18:06:05 +02:00
|
|
|
}
|
|
|
|
/* Then write data to the device */
|
2018-05-25 11:55:27 +02:00
|
|
|
return i2c_write_bytes(dev, addr, data, len, flags | I2C_NOSTART);
|
2018-05-23 15:59:02 +02:00
|
|
|
}
|
|
|
|
#endif /* PERIPH_I2C_NEED_WRITE_REGS */
|