Add I2C frequency to the i2c_msg_s structure

This commit is contained in:
Gregory Nutt 2016-02-01 14:17:20 -06:00
parent f9053182d3
commit 6ad641888b
21 changed files with 308 additions and 252 deletions

View File

@ -11429,3 +11429,9 @@
board with NXP LPCExpresso LPC1768. The GSM module is one of LISA-C200,
LISA-U200 or SARA-G350. The GPS module is one of MAX-M7 or MAX-M8. From
Vladimir Komendantskiy (2016-01-31).
* drivers/, arch/, include/, numerous files: May restructuring of the I2C
interface necessary to eliminate some thread-safety issues inherent in
the legacy I2C interface design. This effects the interface definition,
all I2C clients, and all low-level I2C drivers. I have used caution,
but I still expect a change of this magnitude to introduce some errors.
Any bug reports of bug fixes will be much appreciated (2016-02-01).

@ -1 +1 @@
Subproject commit 4d7a2777081a9773029829531c12b18059fd71e8
Subproject commit 7d40326c7f8ca77993caaa7bb940e3ae2a631f9d

12
TODO
View File

@ -1614,18 +1614,14 @@ o Other drivers (drivers/)
in a multi-tasking I2C environment:
- I2C_SETFREQUENCY: Frequency setting can be overwritten by other
I2C usage.
- I2C_SETADDRESS: The I2C address can and will be changed by other
I2C usage. NOTE also that I2C_SETADDRESS also sets the address width
(either 7 or 10 bits).
- I2C_TRANSFER: This is the only interface that is properly self
contained and protected from most mult-tasking issues. But even
this interface can suffer if there are differing frequency settings.
- I2C_TRANSFER: This interface is almost self but even can suffer
if there are differing frequency settings.
Status: Open
Priority: Medium-High. The fix is easy but effects a lot of software. There
are two ways to fix theses problems: (1) Add a locking method such
as is provided with the SPI interface, or (2) make each interface
self-contained and atomic: Remove the I2C_FREQUENCY and I2C_ADDRESS
methods; Add frequency to the I2C_TRANSFER message structure.
self-contained and atomic: Remove the I2C_FREQUENCY and add
frequency to the I2C_TRANSFER message structure.
o Linux/Cywgin simulation (arch/sim)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

2
arch

@ -1 +1 @@
Subproject commit 490bbe2d7b5b67ff7efc052abb2e2071ff0aac5c
Subproject commit 18c2083af2a73f710e2777c42ccd7ca8ae4096bf

@ -1 +1 @@
Subproject commit 7286dea76c9a19895a14d02b593c4c6356461a9d
Subproject commit 588811152643ca752381a52ec57986c0c4b1a376

View File

@ -266,17 +266,19 @@ uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr)
/* Set up to write the address */
msg[0].addr = priv->lower->address;
msg[0].flags = 0;
msg[0].buffer = &regaddr;
msg[0].length = 1;
msg[0].frequency = priv->lower->frequency;
msg[0].addr = priv->lower->address;
msg[0].flags = 0;
msg[0].buffer = &regaddr;
msg[0].length = 1;
/* Followed by the read data */
msg[1].addr = priv->lower->address;
msg[1].flags = I2C_M_READ;
msg[1].buffer = data;
msg[1].length = 2;
msg[1].frequency = priv->lower->frequency;
msg[1].addr = priv->lower->address;
msg[1].flags = I2C_M_READ;
msg[1].buffer = data;
msg[1].length = 2;
/* Read the register data. The returned value is the number messages
* completed.

View File

@ -79,16 +79,13 @@ int i2c_read(FAR struct i2c_master_s *dev,
/* Setup for the transfer */
msg.addr = config->address,
msg.flags = (flags | I2C_M_READ);
msg.buffer = buffer;
msg.length = buflen;
msg.frequency = config->frequency,
msg.addr = config->address,
msg.flags = (flags | I2C_M_READ);
msg.buffer = buffer;
msg.length = buflen;
/* Then perform the transfer
*
* REVISIT: The following two operations must become atomic in order to
* assure thread safety.
*/
/* Then perform the transfer. */
I2C_SETFREQUENCY(dev, config->frequency);
return I2C_TRANSFER(dev, &msg, 1);

View File

@ -74,16 +74,13 @@ int i2c_write(FAR struct i2c_master_s *dev,
/* Setup for the transfer */
msg.addr = config->address;
msg.flags = (config->addrlen == 10) ? I2C_M_TEN : 0;
msg.buffer = (FAR uint8_t *)buffer; /* Override const */
msg.length = buflen;
msg.frequency = config->frequency,
msg.addr = config->address;
msg.flags = (config->addrlen == 10) ? I2C_M_TEN : 0;
msg.buffer = (FAR uint8_t *)buffer; /* Override const */
msg.length = buflen;
/* Then perform the transfer
*
* REVISIT: The following two operations must become atomic in order to
* assure thread safety.
*/
/* Then perform the transfer. */
I2C_SETFREQUENCY(dev, config->frequency);
return I2C_TRANSFER(dev, &msg, 1);

View File

@ -82,10 +82,11 @@ int i2c_writeread(FAR struct i2c_master_s *dev,
/* Format two messages: The first is a write */
msg[0].addr = config->address;
msg[0].flags = flags;
msg[0].buffer = (FAR uint8_t *)wbuffer; /* Override const */
msg[0].length = wbuflen;
msg[0].frequency = config->frequency,
msg[0].addr = config->address;
msg[0].flags = flags;
msg[0].buffer = (FAR uint8_t *)wbuffer; /* Override const */
msg[0].length = wbuflen;
/* The second is either a read (rbuflen > 0) or a write (rbuflen < 0) with
* no restart.
@ -101,15 +102,12 @@ int i2c_writeread(FAR struct i2c_master_s *dev,
rbuflen = -rbuflen;
}
msg[1].addr = config->address;
msg[1].buffer = rbuffer;
msg[1].length = rbuflen;
msg[1].frequency = config->frequency,
msg[1].addr = config->address;
msg[1].buffer = rbuffer;
msg[1].length = rbuflen;
/* Then perform the transfer
*
* REVISIT: The following two operations must become atomic in order to
* assure thread safety.
*/
/* Then perform the transfer. */
I2C_SETFREQUENCY(dev, config->frequency);
return I2C_TRANSFER(dev, msg, 2);

View File

@ -315,20 +315,22 @@ static int mxt_getreg(FAR struct mxt_dev_s *priv, uint16_t regaddr,
/* Set up to write the address */
addrbuf[0] = regaddr & 0xff;
addrbuf[1] = (regaddr >> 8) & 0xff;
addrbuf[0] = regaddr & 0xff;
addrbuf[1] = (regaddr >> 8) & 0xff;
msg[0].addr = priv->lower->address;
msg[0].flags = 0;
msg[0].buffer = addrbuf;
msg[0].length = 2;
msg[0].frequency = priv->frequency;
msg[0].addr = priv->lower->address;
msg[0].flags = 0;
msg[0].buffer = addrbuf;
msg[0].length = 2;
/* Followed by the read data */
msg[1].addr = priv->lower->address;
msg[1].flags = I2C_M_READ;
msg[1].buffer = buffer;
msg[1].length = buflen;
msg[1].frequency = priv->frequency;
msg[1].addr = priv->lower->address;
msg[1].flags = I2C_M_READ;
msg[1].buffer = buffer;
msg[1].length = buflen;
/* Read the register data. The returned value is the number messages
* completed.
@ -387,20 +389,22 @@ static int mxt_putreg(FAR struct mxt_dev_s *priv, uint16_t regaddr,
/* Set up to write the address */
addrbuf[0] = regaddr & 0xff;
addrbuf[1] = (regaddr >> 8) & 0xff;
addrbuf[0] = regaddr & 0xff;
addrbuf[1] = (regaddr >> 8) & 0xff;
msg[0].addr = priv->lower->address;
msg[0].flags = 0;
msg[0].buffer = addrbuf;
msg[0].length = 2;
msg[0].frequency = priv->frequency;
msg[0].addr = priv->lower->address;
msg[0].flags = 0;
msg[0].buffer = addrbuf;
msg[0].length = 2;
/* Followed by the write data (with no repeated start) */
msg[1].addr = priv->lower->address;
msg[1].flags = I2C_M_NORESTART;
msg[1].buffer = (FAR uint8_t *)buffer;
msg[1].length = buflen;
msg[1].frequency = priv->frequency;
msg[1].addr = priv->lower->address;
msg[1].flags = I2C_M_NORESTART;
msg[1].buffer = (FAR uint8_t *)buffer;
msg[1].length = buflen;
/* Write the register data. The returned value is the number messages
* completed.
@ -1511,7 +1515,9 @@ static int mxt_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
DEBUGASSERT(priv->lower != NULL && ptr != NULL);
priv->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr);
priv->frequency = *ptr;
(void)I2C_SETFREQUENCY(priv->i2c, *ptr);
}
break;
@ -1734,7 +1740,8 @@ static int mxt_hwinitialize(FAR struct mxt_dev_s *priv)
/* Set the selected I2C frequency */
priv->frequency = I2C_SETFREQUENCY(priv->i2c, priv->lower->frequency);
priv->frequency = priv->lower->frequency;
(void)I2C_SETFREQUENCY(priv->i2c, priv->lower->frequency);
/* Read the info registers from the device */

View File

@ -408,19 +408,21 @@ uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
/* Setup 8-bit STMPE811 address write message */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
msg[0].frequency = priv->config->frequency; /* I2C frequency */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
/* Set up the 8-bit STMPE811 data read message */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = &regval; /* Transfer to this address */
msg[1].length = 1; /* Receive one byte following the address
* (then STOP) */
msg[1].frequency = priv->config->frequency; /* I2C frequency */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = &regval; /* Transfer to this address */
msg[1].length = 1; /* Receive one byte following the address
* (then STOP) */
/* Perform the transfer */
@ -472,10 +474,11 @@ void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
/* Setup 8-bit STMPE811 address write message */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = txbuffer; /* Transfer from this address */
msg.length = 2; /* Send two byte following the address
msg.frequency = priv->config->frequency; /* I2C frequency */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = txbuffer; /* Transfer from this address */
msg.length = 2; /* Send two byte following the address
* (then STOP) */
/* Perform the transfer */
@ -513,19 +516,21 @@ uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
/* Setup 8-bit STMPE811 address write message */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
msg[0].frequency = priv->config->frequency; /* I2C frequency */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
/* Set up the 8-bit STMPE811 data read message */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = rxbuffer; /* Transfer to this address */
msg[1].length = 2; /* Receive two bytes following the address
* (then STOP) */
msg[1].frequency = priv->config->frequency; /* I2C frequency */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = rxbuffer; /* Transfer to this address */
msg[1].length = 2; /* Receive two bytes following the address
* (then STOP) */
/* Perform the transfer */

View File

@ -430,12 +430,13 @@ static int tsc2007_activate(FAR struct tsc2007_dev_s *priv, uint8_t cmd)
* activation command (ACKed).
*/
data = TSC2007_SETUP;
data = TSC2007_SETUP;
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = &data; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address */
msg.frequency = priv->config->frequency; /* I2C frequency */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = &data; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address */
/* Ignore errors from the setup command (because it is not ACKed) */
@ -443,12 +444,13 @@ static int tsc2007_activate(FAR struct tsc2007_dev_s *priv, uint8_t cmd)
/* Now activate the A/D converter */
data = cmd;
data = cmd;
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = &data; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address */
msg.frequency = priv->config->frequency; /* I2C frequency */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = &data; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address */
ret = I2C_TRANSFER(priv->i2c, &msg, 1);
if (ret < 0)
@ -483,10 +485,11 @@ static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd)
* STOP condition...
*/
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = &cmd; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address */
msg.frequency = priv->config->frequency; /* I2C frequency */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = &cmd; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address */
ret = I2C_TRANSFER(priv->i2c, &msg, 1);
if (ret < 0)
@ -527,10 +530,11 @@ static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd)
* data byte has been received...
*/
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = I2C_M_READ; /* Read transaction, beginning with START */
msg.buffer = data12; /* Transfer to this address */
msg.length = 2; /* Read two bytes following the address */
msg.frequency = priv->config->frequency; /* I2C frequency */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = I2C_M_READ; /* Read transaction, beginning with START */
msg.buffer = data12; /* Transfer to this address */
msg.length = 2; /* Read two bytes following the address */
ret = I2C_TRANSFER(priv->i2c, &msg, 1);
if (ret < 0)
@ -1068,7 +1072,8 @@ static int tsc2007_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
DEBUGASSERT(priv->config != NULL && ptr != NULL);
priv->config->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr);
priv->config->frequency = *ptr;
(void)I2C_SETFREQUENCY(priv->i2c, *ptr);
}
break;

View File

@ -82,11 +82,12 @@ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval)
/* Setup 8-bit SSD1306 address write message */
msg.addr = priv->addr; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = txbuffer; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address
* (then STOP) */
msg.frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */
msg.addr = priv->addr; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = txbuffer; /* Transfer from this address */
msg.length = 1; /* Send one byte following the address
* (then STOP) */
/* Perform the transfer */
@ -117,11 +118,12 @@ void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len)
/* Setup 8-bit SSD1306 address write message */
msg.addr = priv->addr; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = data; /* Transfer from this address */
msg.length = len; /* Send one byte following the address
* (then STOP) */
msg.frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */
msg.addr = priv->addr; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = data; /* Transfer from this address */
msg.length = len; /* Send one byte following the address
* (then STOP) */
/* Perform the transfer */

View File

@ -22,7 +22,12 @@ config LIS331DL
bool "ST LIS331DL device support"
default n
select I2C
select I2C_TRANSFER
config LIS331DL_I2C_FREQUENCY
bool "LIS331DL I2C frequency"
default 100000
range 1 100000
depends on LIS331DL
config SN_LSM9DS1
bool "STMicro LSM9DS1 support"

View File

@ -76,19 +76,21 @@ uint8_t adxl345_getreg8(FAR struct adxl345_dev_s *priv, uint8_t regaddr)
/* Setup 8-bit ADXL345 address write message */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
msg[0].frequency = priv->config->frequency; /* I2C frequency */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
/* Set up the 8-bit ADXL345 data read message */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = &regval; /* Transfer to this address */
msg[1].length = 1; /* Receive one byte following the address
* (then STOP) */
msg[1].frequency = priv->config->frequency; /* I2C frequency */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = &regval; /* Transfer to this address */
msg[1].length = 1; /* Receive one byte following the address
* (then STOP) */
/* Perform the transfer */
@ -140,11 +142,12 @@ void adxl345_putreg8(FAR struct adxl345_dev_s *priv,
/* Setup 8-bit ADXL345 address write message */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = txbuffer; /* Transfer from this address */
msg.length = 2; /* Send two byte following the address
* (then STOP) */
msg.frequency = priv->config->frequency; /* I2C frequency */
msg.addr = priv->config->address; /* 7-bit address */
msg.flags = 0; /* Write transaction, beginning with START */
msg.buffer = txbuffer; /* Transfer from this address */
msg.length = 2; /* Send two byte following the address
* (then STOP) */
/* Perform the transfer */
@ -180,19 +183,21 @@ uint16_t adxl345_getreg16(FAR struct adxl345_dev_s *priv, uint8_t regaddr)
/* Setup 8-bit ADXL345 address write message */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
msg[0].frequency = priv->config->frequency; /* I2C frequency */
msg[0].addr = priv->config->address; /* 7-bit address */
msg[0].flags = 0; /* Write transaction, beginning with START */
msg[0].buffer = &regaddr; /* Transfer from this address */
msg[0].length = 1; /* Send one byte following the address
* (no STOP) */
/* Set up the 8-bit ADXL345 data read message */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = rxbuffer; /* Transfer to this address */
msg[1].length = 2; /* Receive two bytes following the address
* (then STOP) */
msg[1].frequency = priv->config->frequency; /* I2C frequency */
msg[1].addr = priv->config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
msg[1].buffer = rxbuffer; /* Transfer to this address */
msg[1].length = 2; /* Receive two bytes following the address
* (then STOP) */
/* Perform the transfer */

View File

@ -54,6 +54,11 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_LIS331DL_I2C_FREQUENCY
# define CONFIG_LIS331DL_I2C_FREQUENCY
#endif
/* LIS331DL Internal Registers **********************************************/
#define ST_LIS331DL_WHOAMI 0x0F /* who am I register */
@ -182,16 +187,18 @@ static int lis331dl_access(FAR struct lis331dl_dev_s *dev, uint8_t subaddr,
struct i2c_msg_s msgv[2] =
{
{
.addr = dev->address,
.flags = 0,
.buffer = &subaddr,
.length = 1
.frequency = CONFIG_LIS331DL_I2C_FREQUENCY,
.addr = dev->address,
.flags = 0,
.buffer = &subaddr,
.length = 1
},
{
.addr = dev->address,
.flags = flags,
.buffer = buf,
.length = length
.frequency = CONFIG_LIS331DL_I2C_FREQUENCY,
.addr = dev->address,
.flags = flags,
.buffer = buf,
.length = length
}
};

View File

@ -54,6 +54,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Driver Definitions *******************************************************/
#define MAX_REFCLK_FREQ 75000000
@ -133,15 +134,17 @@ static int cs2100_write_reg(FAR const struct cs2100_config_s *config,
/* Construct the I2C message (write N+1 bytes with no restart) */
msgs[0].addr = config->i2caddr;
msgs[0].flags = 0;
msgs[0].buffer = &regaddr;
msgs[0].length = 1;
msga[0].frequency = config->i2cfreq;
msgs[0].addr = config->i2caddr;
msgs[0].flags = 0;
msgs[0].buffer = &regaddr;
msgs[0].length = 1;
msgs[1].addr = config->i2caddr;
msgs[1].flags = I2C_M_NORESTART;
msgs[1].buffer = &regval;
msgs[1].length = 1;
msga[1].frequency = config->i2cfreq;
msgs[1].addr = config->i2caddr;
msgs[1].flags = I2C_M_NORESTART;
msgs[1].buffer = &regval;
msgs[1].length = 1;
/* Send the message */
@ -175,20 +178,22 @@ static int cs2100_read_reg(FAR const struct cs2100_config_s *config,
/* Construct the I2C message (write 1 bytes, restart, read N bytes) */
msg.addr = config->i2caddr;
msg.flags = 0;
msg.buffer = &regaddr;
msg.length = 1;
msg.frequency = config->i2cfreq;
msg.addr = config->i2caddr;
msg.flags = 0;
msg.buffer = &regaddr;
msg.length = 1;
/* Send the address followed by a STOP */
ret = I2C_TRANSFER(config->i2c, &msg, 1);
if (ret == OK)
{
msg.addr = config->i2caddr;
msg.flags = I2C_M_READ;
msg.buffer = regval;
msg.length = 1;
msg.frequency = config->i2cfreq;
msg.addr = config->i2caddr;
msg.flags = I2C_M_READ;
msg.buffer = regval;
msg.length = 1;
/* Read the register beginning with another START */
@ -229,16 +234,17 @@ static int cs2100_write_ratio(FAR const struct cs2100_config_s *config,
/* Construct the I2C message (write N+1 bytes with no restart) */
buffer[0] = CS2100_RATIO0;
buffer[1] = (uint8_t)(ratio >> 24);
buffer[2] = (uint8_t)((ratio >> 16) & 0xff);
buffer[3] = (uint8_t)((ratio >> 8) & 0xff);
buffer[4] = (uint8_t)(ratio & 0xff);
buffer[0] = CS2100_RATIO0;
buffer[1] = (uint8_t)(ratio >> 24);
buffer[2] = (uint8_t)((ratio >> 16) & 0xff);
buffer[3] = (uint8_t)((ratio >> 8) & 0xff);
buffer[4] = (uint8_t)(ratio & 0xff);
msg.addr = config->i2caddr;
msg.flags = 0;
msg.buffer = buffer;
msg.length = 5;
msg.frequency = config->i2cfreq;
msg.addr = config->i2caddr;
msg.flags = 0;
msg.buffer = buffer;
msg.length = 5;
/* Send the message */
@ -272,22 +278,24 @@ static int cs2100_read_ratio(FAR const struct cs2100_config_s *config,
/* Construct the I2C message (write N+1 bytes with no restart) */
buffer[0] = CS2100_RATIO0;
buffer[0] = CS2100_RATIO0;
msg.addr = config->i2caddr;
msg.flags = 0;
msg.buffer = buffer;
msg.length = 1;
msg.frequency = config->i2cfreq;
msg.addr = config->i2caddr;
msg.flags = 0;
msg.buffer = buffer;
msg.length = 1;
/* Send the address followed by a STOP */
ret = I2C_TRANSFER(config->i2c, &msg, 1);
if (ret == OK)
{
msg.addr = config->i2caddr;
msg.flags = I2C_M_READ;
msg.buffer = buffer;
msg.length = 4;
msg.frequency = config->i2cfreq;
msg.addr = config->i2caddr;
msg.flags = I2C_M_READ;
msg.buffer = buffer;
msg.length = 4;
/* Read the ratio registers beginning with another START */

View File

@ -298,33 +298,37 @@ int up_rtc_getdatetime(FAR struct tm *tp)
/* Select to begin reading at the seconds register */
secaddr = DSXXXX_TIME_SECR;
secaddr = DSXXXX_TIME_SECR;
msg[0].addr = DS3231_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = &secaddr;
msg[0].length = 1;
msg[0].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[0].addr = DS3231_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = &secaddr;
msg[0].length = 1;
/* Set up to read 7 registers: secondss, minutes, hour, day-of-week, date,
* month, year
*/
msg[1].addr = DS3231_I2C_ADDRESS;
msg[1].flags = I2C_M_READ;
msg[1].buffer = buffer;
msg[1].length = 7;
msg[1].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[1].addr = DS3231_I2C_ADDRESS;
msg[1].flags = I2C_M_READ;
msg[1].buffer = buffer;
msg[1].length = 7;
/* Read the seconds register again */
msg[2].addr = DS3231_I2C_ADDRESS;
msg[2].flags = 0;
msg[2].buffer = &secaddr;
msg[2].length = 1;
msg[2].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[2].addr = DS3231_I2C_ADDRESS;
msg[2].flags = 0;
msg[2].buffer = &secaddr;
msg[2].length = 1;
msg[3].addr = DS3231_I2C_ADDRESS;
msg[3].flags = I2C_M_READ;
msg[3].buffer = &seconds;
msg[3].length = 1;
msg[3].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[3].addr = DS3231_I2C_ADDRESS;
msg[3].flags = I2C_M_READ;
msg[3].buffer = &seconds;
msg[3].length = 1;
/* Configure I2C before using it */
@ -525,22 +529,25 @@ int up_rtc_settime(FAR const struct timespec *tp)
/* Setup the I2C message */
msg[0].addr = DS3231_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = buffer;
msg[0].length = 8;
msg[0].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[0].addr = DS3231_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = buffer;
msg[0].length = 8;
/* Read back the seconds register */
msg[1].addr = DS3231_I2C_ADDRESS;
msg[1].flags = 0;
msg[1].buffer = buffer;
msg[1].length = 1;
msg[1].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[1].addr = DS3231_I2C_ADDRESS;
msg[1].flags = 0;
msg[1].buffer = buffer;
msg[1].length = 1;
msg[2].addr = DS3231_I2C_ADDRESS;
msg[2].flags = I2C_M_READ;
msg[2].buffer = &seconds;
msg[2].length = 1;
msg[2].frequency = CONFIG_DS3231_I2C_FREQUENCY;
msg[2].addr = DS3231_I2C_ADDRESS;
msg[2].flags = I2C_M_READ;
msg[2].buffer = &seconds;
msg[2].length = 1;
/* Configure I2C before using it */

View File

@ -297,33 +297,37 @@ int up_rtc_getdatetime(FAR struct tm *tp)
/* Select to begin reading at the seconds register */
secaddr = PCF85263_RTC_SECONDS;
secaddr = PCF85263_RTC_SECONDS;
msg[0].addr = PCF85263_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = &secaddr;
msg[0].length = 1;
msg[0].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[0].addr = PCF85263_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = &secaddr;
msg[0].length = 1;
/* Set up to read 7 registers: secondss, minutes, hour, day-of-week, date,
* month, year
*/
msg[1].addr = PCF85263_I2C_ADDRESS;
msg[1].flags = I2C_M_READ;
msg[1].buffer = buffer;
msg[1].length = 7;
msg[1].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[1].addr = PCF85263_I2C_ADDRESS;
msg[1].flags = I2C_M_READ;
msg[1].buffer = buffer;
msg[1].length = 7;
/* Read the seconds register again */
msg[2].addr = PCF85263_I2C_ADDRESS;
msg[2].flags = 0;
msg[2].buffer = &secaddr;
msg[2].length = 1;
msg[2].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[2].addr = PCF85263_I2C_ADDRESS;
msg[2].flags = 0;
msg[2].buffer = &secaddr;
msg[2].length = 1;
msg[3].addr = PCF85263_I2C_ADDRESS;
msg[3].flags = I2C_M_READ;
msg[3].buffer = &seconds;
msg[3].length = 1;
msg[3].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[3].addr = PCF85263_I2C_ADDRESS;
msg[3].flags = I2C_M_READ;
msg[3].buffer = &seconds;
msg[3].length = 1;
/* Configure I2C before using it */
@ -487,24 +491,27 @@ int up_rtc_settime(FAR const struct timespec *tp)
/* Setup the I2C message */
msg[0].addr = PCF85263_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = buffer;
msg[0].length = 9;
msg[0].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[0].addr = PCF85263_I2C_ADDRESS;
msg[0].flags = 0;
msg[0].buffer = buffer;
msg[0].length = 9;
/* Read back the seconds register */
cmd = PCF85263_RTC_SECONDS;
cmd = PCF85263_RTC_SECONDS;
msg[1].addr = PCF85263_I2C_ADDRESS;
msg[1].flags = 0;
msg[1].buffer = &cmd;
msg[1].length = 1;
msg[1].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[1].addr = PCF85263_I2C_ADDRESS;
msg[1].flags = 0;
msg[1].buffer = &cmd;
msg[1].length = 1;
msg[2].addr = PCF85263_I2C_ADDRESS;
msg[2].flags = I2C_M_READ;
msg[2].buffer = &seconds;
msg[2].length = 1;
msg[2].frequency = CONFIG_PCF85263_I2C_FREQUENCY;
msg[2].addr = PCF85263_I2C_ADDRESS;
msg[2].flags = I2C_M_READ;
msg[2].buffer = &seconds;
msg[2].length = 1;
/* Configure I2C before using it */

View File

@ -155,10 +155,11 @@ struct i2c_config_s
struct i2c_msg_s
{
uint32_t frequency; /* I2C frequency */
uint16_t addr; /* Slave address (7- or 10-bit) */
uint16_t flags; /* See I2C_M_* definitions */
uint8_t *buffer; /* Buffer to be transferred */
ssize_t length; /* Length of the buffer in byetes */
ssize_t length; /* Length of the buffer in bytes */
};
/* I2C private data. This structure only defines the initial fields of the

View File

@ -160,6 +160,7 @@
struct cs2100_config_s
{
FAR struct i2c_master_s *i2c; /* Instance of an I2C interface */
uint32_t i2cfreq; /* I2C frequency */
uint32_t refclk; /* RefClk/XTAL frequency */
uint32_t clkin; /* Frequency CLK_IN provided to the CS2100-CP */
uint32_t clkout; /* Desired CLK_OUT frequency */