diff --git a/ChangeLog b/ChangeLog index 1f05f87921..78aa885aab 100755 --- a/ChangeLog +++ b/ChangeLog @@ -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). diff --git a/Documentation b/Documentation index 4d7a277708..7d40326c7f 160000 --- a/Documentation +++ b/Documentation @@ -1 +1 @@ -Subproject commit 4d7a2777081a9773029829531c12b18059fd71e8 +Subproject commit 7d40326c7f8ca77993caaa7bb940e3ae2a631f9d diff --git a/TODO b/TODO index 854b3996e4..57f3b74f8b 100644 --- a/TODO +++ b/TODO @@ -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) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/arch b/arch index 490bbe2d7b..18c2083af2 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit 490bbe2d7b5b67ff7efc052abb2e2071ff0aac5c +Subproject commit 18c2083af2a73f710e2777c42ccd7ca8ae4096bf diff --git a/configs b/configs index 7286dea76c..5888111526 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit 7286dea76c9a19895a14d02b593c4c6356461a9d +Subproject commit 588811152643ca752381a52ec57986c0c4b1a376 diff --git a/drivers/audio/wm8904.c b/drivers/audio/wm8904.c index a37c2cf5d4..cfc04a3ddc 100644 --- a/drivers/audio/wm8904.c +++ b/drivers/audio/wm8904.c @@ -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 = ®addr; - msg[0].length = 1; + msg[0].frequency = priv->lower->frequency; + msg[0].addr = priv->lower->address; + msg[0].flags = 0; + msg[0].buffer = ®addr; + 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. diff --git a/drivers/i2c/i2c_read.c b/drivers/i2c/i2c_read.c index 1c0a840cd4..72134c2c50 100644 --- a/drivers/i2c/i2c_read.c +++ b/drivers/i2c/i2c_read.c @@ -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); diff --git a/drivers/i2c/i2c_write.c b/drivers/i2c/i2c_write.c index d98be5e293..11eb25cc7d 100644 --- a/drivers/i2c/i2c_write.c +++ b/drivers/i2c/i2c_write.c @@ -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); diff --git a/drivers/i2c/i2c_writeread.c b/drivers/i2c/i2c_writeread.c index da421680f6..265f272d1d 100644 --- a/drivers/i2c/i2c_writeread.c +++ b/drivers/i2c/i2c_writeread.c @@ -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); diff --git a/drivers/input/mxt.c b/drivers/input/mxt.c index f5ebec8e89..768ebe095b 100644 --- a/drivers/input/mxt.c +++ b/drivers/input/mxt.c @@ -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 */ diff --git a/drivers/input/stmpe811_base.c b/drivers/input/stmpe811_base.c index 72fa6c20f4..c115d985fe 100644 --- a/drivers/input/stmpe811_base.c +++ b/drivers/input/stmpe811_base.c @@ -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 = ®addr; /* 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 = ®addr; /* 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 = ®val; /* 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 = ®val; /* 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 = ®addr; /* 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 = ®addr; /* 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 */ diff --git a/drivers/input/tsc2007.c b/drivers/input/tsc2007.c index 82f2d74103..e3ae851688 100644 --- a/drivers/input/tsc2007.c +++ b/drivers/input/tsc2007.c @@ -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; diff --git a/drivers/lcd/ssd1306_i2c.c b/drivers/lcd/ssd1306_i2c.c index ffc72b075e..1a5edaa6d1 100644 --- a/drivers/lcd/ssd1306_i2c.c +++ b/drivers/lcd/ssd1306_i2c.c @@ -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 */ diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 46f0e3b2c9..abbe171699 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -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" diff --git a/drivers/sensors/adxl345_i2c.c b/drivers/sensors/adxl345_i2c.c index b5ece68727..a2dfd81961 100644 --- a/drivers/sensors/adxl345_i2c.c +++ b/drivers/sensors/adxl345_i2c.c @@ -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 = ®addr; /* 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 = ®addr; /* 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 = ®val; /* 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 = ®val; /* 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 = ®addr; /* 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 = ®addr; /* 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 */ diff --git a/drivers/sensors/lis331dl.c b/drivers/sensors/lis331dl.c index de4887ef2d..c563d53080 100644 --- a/drivers/sensors/lis331dl.c +++ b/drivers/sensors/lis331dl.c @@ -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 } }; diff --git a/drivers/timers/cs2100-cp.c b/drivers/timers/cs2100-cp.c index 10da98d4b3..11ed144cb4 100644 --- a/drivers/timers/cs2100-cp.c +++ b/drivers/timers/cs2100-cp.c @@ -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 = ®addr; - msgs[0].length = 1; + msga[0].frequency = config->i2cfreq; + msgs[0].addr = config->i2caddr; + msgs[0].flags = 0; + msgs[0].buffer = ®addr; + msgs[0].length = 1; - msgs[1].addr = config->i2caddr; - msgs[1].flags = I2C_M_NORESTART; - msgs[1].buffer = ®val; - msgs[1].length = 1; + msga[1].frequency = config->i2cfreq; + msgs[1].addr = config->i2caddr; + msgs[1].flags = I2C_M_NORESTART; + msgs[1].buffer = ®val; + 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 = ®addr; - msg.length = 1; + msg.frequency = config->i2cfreq; + msg.addr = config->i2caddr; + msg.flags = 0; + msg.buffer = ®addr; + 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 */ diff --git a/drivers/timers/ds3231.c b/drivers/timers/ds3231.c index 19c3a3e237..60292c4fed 100644 --- a/drivers/timers/ds3231.c +++ b/drivers/timers/ds3231.c @@ -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 */ diff --git a/drivers/timers/pcf85263.c b/drivers/timers/pcf85263.c index eaf8b6d10f..c8b85f1162 100644 --- a/drivers/timers/pcf85263.c +++ b/drivers/timers/pcf85263.c @@ -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 */ diff --git a/include/nuttx/i2c/i2c_master.h b/include/nuttx/i2c/i2c_master.h index dee94a5e7a..4040efa24e 100644 --- a/include/nuttx/i2c/i2c_master.h +++ b/include/nuttx/i2c/i2c_master.h @@ -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 diff --git a/include/nuttx/timers/cs2100-cp.h b/include/nuttx/timers/cs2100-cp.h index 5d62149134..fe72836770 100644 --- a/include/nuttx/timers/cs2100-cp.h +++ b/include/nuttx/timers/cs2100-cp.h @@ -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 */