-
Home
-
doc
-
support
-
driver
-
i2c
i2c.c
View on Github
/**
* @file i2c.c
* @author Sebastien CAUX (sebcaux)
* @copyright Robotips 2016
*
* @date March 01, 2016, 19:10 PM
*
* @brief I2C communication support driver, global function peripheral
* independent
*/
#include "i2c.h"
/**
* @brief Read a register at address 'reg' in i2c chip with address 'address'
* @param device i2c bus device number
* @param address i2c chip address
* @param reg reg address to read
* @param flags flags to configure the request frame
* @return data received
*/
uint16_t i2c_readreg(rt_dev_t device, uint16_t address, uint16_t reg, uint8_t flags)
{
uint16_t value = 0;
i2c_start(device);
if (i2c_putc(device, (uint8_t)(address & 0xFE)) == -1)
{
return 0;
}
if (flags & I2C_REGADDR16)
{
if (i2c_putc(device, (uint8_t)(reg>>8)) == -1)
{
return 0;
}
}
if (i2c_putc(device, (uint8_t)(reg&0x00FF)) == -1)
{
return 0;
}
if (flags & I2C_READ_STOPSTART)
{
i2c_stop(device);
i2c_start(device);
}
else
{
i2c_restart(device);
}
if (i2c_putc(device, address | 0x01) == -1)
{
return 0;
}
if (flags & I2C_REG16)
{
value = i2c_getc(device)<<8;
}
value += i2c_getc(device);
i2c_nack(device);
i2c_stop(device);
return value;
}
/**
* @brief Read 'size' registers begining at address 'reg' in i2c chip with address 'address'
* @param device i2c bus device number
* @param address i2c chip address
* @param reg reg address to start read
* @param size number of reg to read
* @param flags flags to configure the request frame
* @return 0 if success
*/
ssize_t i2c_readregs(rt_dev_t device, uint16_t address, uint16_t reg, uint8_t regs[], size_t size, uint8_t flags)
{
size_t id;
uint8_t *ptrreg;
i2c_start(device);
if (i2c_putc(device, (uint8_t)(address & 0xFE)) != 0)
{
return -1;
}
if (flags & I2C_REGADDR16)
{
if (i2c_putc(device, (uint8_t)(reg>>8)) != 0)
{
return -1;
}
}
if (i2c_putc(device, (uint8_t)(reg&0x00FF)) != 0)
{
return -1;
}
if (flags & I2C_READ_STOPSTART)
{
i2c_stop(device);
i2c_start(device);
}
else
{
i2c_restart(device);
}
if (i2c_putc(device, address | 0x01) != 0)
{
return -1;
}
ptrreg = regs;
for (id=0; id<size; id++)
{
if (flags & I2C_REG16)
{
*ptrreg = i2c_getc(device)<<8;
ptrreg++;
}
*ptrreg = i2c_getc(device);
ptrreg++;
if (id!=size-1)
{
i2c_ack(device);
}
else
{
i2c_nack(device);
i2c_stop(device);
}
}
return 0;
}
/**
* @brief Write 'value' in register at address 'reg' in i2c chip with address 'address'
* @param device i2c bus device number
* @param address i2c chip address
* @param reg reg address to write
* @param value value to write
* @param flags flags to configure the request frame
* @return 0 if success
*/
int i2c_writereg(rt_dev_t device, uint16_t address, uint16_t reg, uint16_t value, uint8_t flags)
{
i2c_start(device);
if (i2c_putc(device, (uint8_t)(address & 0xFE)) != 0)
{
return -1;
}
if (flags & I2C_REGADDR16)
{
if (i2c_putc(device, (uint8_t)(reg>>8)) != 0)
{
return -1;
}
}
if (i2c_putc(device, (uint8_t)(reg&0x00FF)) != 0)
{
return -1;
}
if (flags & I2C_REG16)
{
if (i2c_putc(device, (uint8_t)(value>>8)) != 0)
{
return -1;
}
}
if (i2c_putc(device, (uint8_t)(value&0x00FF)) != 0)
{
return -1;
}
i2c_stop(device);
return 0;
}
/**
* @brief Write 'regs' in registers that start at address 'reg' in i2c chip
* with address 'address'
* @param device i2c bus device number
* @param address i2c chip address
* @param reg reg address to write
* @param regs values to write
* @param size number of reg to write
* @param flags flags to configure the request frame
* @return 0 if success
*/
int i2c_writeregs(rt_dev_t device, uint16_t address, uint16_t reg, uint8_t regs[], size_t size, uint8_t flags)
{
size_t id;
uint8_t *ptrreg;
i2c_start(device);
if (i2c_putc(device, (uint8_t)(address & 0xFE)) != 0)
{
return -1;
}
if (flags & I2C_REGADDR16)
{
if (i2c_putc(device, (uint8_t)(reg>>8)) != 0)
{
return -1;
}
}
if (i2c_putc(device, (uint8_t)(reg&0x00FF)) != 0)
{
return -1;
}
ptrreg = regs;
for (id=0; id<size; id++)
{
if (flags & I2C_REG16)
{
if (i2c_putc(device, *(ptrreg++)) != 0)
{
return -1;
}
}
if (i2c_putc(device, *(ptrreg++)) != 0)
{
return -1;
}
}
i2c_stop(device);
return 0;
}