You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2024/08/07 15:13:44 UTC
(nuttx) branch master updated (52583fc17e -> 5df3f5d4f7)
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from 52583fc17e tools/ci: Add Rust Target for QEMU RISC-V 64-bit
new 9ffac12465 spi: Remove useless restrictions
new a6cea0d82e Restriction declaration spi_slave_unlink function
new 2bf13ffbb0 spi: Optimize access to private data
new 6114c0b948 i2c: Remove useless restrictions
new f4a234613e Add I2C Slave driver
new 1ea19e7c54 fix i2c slave register failed
new 2093038315 add setup and shutdown for i2c master and slave
new 4e6f3e9360 I2c slave: Add POLLOUT event for notifie slave write success
new f94160095e Adapt i2c slave callback interface for rp2040 and s32k11x
new 75fa94af02 i2c_slave: add poll waiters array
new 5df3f5d4f7 Added the documentation about the iic slave driver
The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
Documentation/components/drivers/special/i2c.rst | 8 +
arch/arm/src/rp2040/rp2040_i2c_slave.c | 15 +-
arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c | 12 +-
.../s32k1xx/rddrone-bms772/src/s32k1xx_smbus_sbd.c | 15 +-
drivers/i2c/CMakeLists.txt | 4 +
drivers/i2c/Kconfig | 31 ++
drivers/i2c/Make.defs | 4 +
drivers/i2c/i2c_driver.c | 31 +-
drivers/i2c/i2c_slave_driver.c | 596 +++++++++++++++++++++
drivers/i2c/pca9540bdp.c | 3 -
drivers/i2c/tca9548a.c | 3 -
drivers/spi/spi_bitbang.c | 3 -
drivers/spi/spi_driver.c | 34 +-
drivers/spi/spi_slave_driver.c | 43 +-
drivers/spi/spi_transfer.c | 3 -
include/nuttx/i2c/i2c_master.h | 34 ++
include/nuttx/i2c/i2c_slave.h | 70 ++-
17 files changed, 848 insertions(+), 61 deletions(-)
create mode 100644 drivers/i2c/i2c_slave_driver.c
(nuttx) 09/11: Adapt i2c slave callback interface for rp2040 and s32k11x
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit f94160095ea2411317b3b37f177acbca4544ecd1
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Thu Dec 21 10:43:26 2023 +0800
Adapt i2c slave callback interface for rp2040 and s32k11x
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
arch/arm/src/rp2040/rp2040_i2c_slave.c | 15 ++++++++++++---
arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c | 12 +++++++++++-
boards/arm/s32k1xx/rddrone-bms772/src/s32k1xx_smbus_sbd.c | 15 ++++++++++++---
3 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/arch/arm/src/rp2040/rp2040_i2c_slave.c b/arch/arm/src/rp2040/rp2040_i2c_slave.c
index af9e057dc5..c2b1d9f066 100644
--- a/arch/arm/src/rp2040/rp2040_i2c_slave.c
+++ b/arch/arm/src/rp2040/rp2040_i2c_slave.c
@@ -152,6 +152,7 @@ static int i2c_interrupt(int irq, void *context, void *arg)
rp2040_i2c_slave_t *priv = (rp2040_i2c_slave_t *)arg;
uint32_t data_cmd;
uint32_t state;
+ int length;
state = getreg32(RP2040_I2C_IC_INTR_STAT(priv->controller));
@@ -159,7 +160,8 @@ static int i2c_interrupt(int irq, void *context, void *arg)
if (state & RP2040_I2C_IC_INTR_STAT_R_RD_REQ)
{
- if (priv->tx_buf_ptr < priv->tx_buf_end)
+ length = priv->tx_buf_end - priv->tx_buf_ptr;
+ if (length > 0)
{
while (priv->tx_buf_ptr < priv->tx_buf_end
&& getreg32(RP2040_I2C_IC_TXFLR(priv->controller))
@@ -168,6 +170,11 @@ static int i2c_interrupt(int irq, void *context, void *arg)
putreg32(*priv->tx_buf_ptr++,
RP2040_I2C_IC_DATA_CMD(priv->controller));
}
+
+ if (priv->callback != NULL)
+ {
+ priv->callback(priv, I2CS_TX_COMPLETE, length);
+ }
}
else
{
@@ -203,7 +210,8 @@ static int i2c_interrupt(int irq, void *context, void *arg)
{
if (priv->callback != NULL && priv->rx_buf_ptr > priv->rx_buffer)
{
- priv->callback(priv, priv->rx_buf_ptr - priv->rx_buffer);
+ priv->callback(priv, I2CS_RX_COMPLETE,
+ priv->rx_buf_ptr - priv->rx_buffer);
priv->rx_buf_ptr = priv->rx_buffer;
}
@@ -216,7 +224,8 @@ static int i2c_interrupt(int irq, void *context, void *arg)
{
if (priv->callback != NULL && priv->rx_buf_ptr > priv->rx_buffer)
{
- priv->callback(priv, priv->rx_buf_ptr - priv->rx_buffer);
+ priv->callback(priv, I2CS_RX_COMPLETE,
+ priv->rx_buf_ptr - priv->rx_buffer);
priv->rx_buf_ptr = priv->rx_buffer;
}
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c b/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c
index 32792bbb0f..533f97c585 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c
@@ -427,9 +427,19 @@ static int s32k1xx_lpi2c_slave_isr_process(
if ((priv->read_bufindex > 0) && (priv->callback != NULL))
{
- priv->callback(priv->callback_arg, priv->read_bufindex);
+ priv->callback(priv->callback_arg, I2CS_RX_COMPLETE,
+ priv->read_bufindex);
priv->read_bufindex = 0;
}
+
+ /* Execute the registered callback function if data was send */
+
+ if ((priv->write_bufindex > 0) && (priv->callback != NULL))
+ {
+ priv->callback(priv->callback_arg, I2CS_TX_COMPLETE,
+ priv->write_bufindex);
+ priv->write_bufindex = 0;
+ }
}
/* Slave Bit Error (abort current transfer) */
diff --git a/boards/arm/s32k1xx/rddrone-bms772/src/s32k1xx_smbus_sbd.c b/boards/arm/s32k1xx/rddrone-bms772/src/s32k1xx_smbus_sbd.c
index c870a77e24..0d48fb45a0 100644
--- a/boards/arm/s32k1xx/rddrone-bms772/src/s32k1xx_smbus_sbd.c
+++ b/boards/arm/s32k1xx/rddrone-bms772/src/s32k1xx_smbus_sbd.c
@@ -384,10 +384,12 @@ static ssize_t smbus_sbd_write(struct file *filep, const char *buffer,
*
****************************************************************************/
-static int smbus_sbd_callback(void *arg, size_t rx_len)
+static int smbus_sbd_callback(void *arg, i2c_slave_complete_t state,
+ size_t rx_len)
{
struct smbus_sbd_dev_s *dev;
int buffer_length;
+ int ret = OK;
int i;
/* Retrieve the pointer to the SMBus SBD slave device struct */
@@ -726,8 +728,15 @@ static int smbus_sbd_callback(void *arg, size_t rx_len)
* request has been received.
*/
- return I2CS_WRITE(dev->i2c_slave_dev, (const uint8_t *)dev->write_buffer,
- buffer_length);
+ ret = I2CS_WRITE(dev->i2c_slave_dev, (const uint8_t *)dev->write_buffer,
+ buffer_length);
+ if (ret >= 0)
+ {
+ dev->i2c_slave_dev->callback(dev->i2c_slave_dev->callback_arg,
+ I2CS_TX_COMPLETE, buffer_length);
+ }
+
+ return ret;
}
/****************************************************************************
(nuttx) 06/11: fix i2c slave register failed
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 1ea19e7c540d348925ef0c75b6cf15f6fbdf842d
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Wed Nov 8 15:01:09 2023 +0800
fix i2c slave register failed
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/i2c_slave_driver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c_slave_driver.c b/drivers/i2c/i2c_slave_driver.c
index 1cb71262e1..44160017dd 100644
--- a/drivers/i2c/i2c_slave_driver.c
+++ b/drivers/i2c/i2c_slave_driver.c
@@ -509,7 +509,7 @@ int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
}
ret = I2CS_REGISTERCALLBACK(priv->dev, i2c_slave_callback, priv);
- if (ret > 0)
+ if (ret >= 0)
{
return OK;
}
(nuttx) 02/11: Restriction declaration spi_slave_unlink function
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit a6cea0d82e883564075c13b2e45e10dac4959823
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Thu Oct 26 15:11:35 2023 +0800
Restriction declaration spi_slave_unlink function
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/spi/spi_slave_driver.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/spi/spi_slave_driver.c b/drivers/spi/spi_slave_driver.c
index d23fadf14a..c80ab1ed39 100644
--- a/drivers/spi/spi_slave_driver.c
+++ b/drivers/spi/spi_slave_driver.c
@@ -106,7 +106,10 @@ static ssize_t spi_slave_write(FAR struct file *filep,
FAR const char *buffer, size_t buflen);
static int spi_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup);
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int spi_slave_unlink(FAR struct inode *inode);
+#endif
/* SPI Slave driver methods */
(nuttx) 11/11: Added the documentation about the iic slave driver
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 5df3f5d4f7289142979215232d8f3d299628c7bb
Author: zhangshoukui <zh...@xiaomi.com>
AuthorDate: Wed Aug 7 10:16:06 2024 +0800
Added the documentation about the iic slave driver
Signed-off-by: zhangshoukui <zh...@xiaomi.com>
---
Documentation/components/drivers/special/i2c.rst | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/components/drivers/special/i2c.rst b/Documentation/components/drivers/special/i2c.rst
index fa722cbf2b..08d1464f31 100644
--- a/Documentation/components/drivers/special/i2c.rst
+++ b/Documentation/components/drivers/special/i2c.rst
@@ -21,3 +21,11 @@ I2C Device Drivers
- **Examples**: ``arch/z80/src/ez80/ez80_i2c.c``,
``arch/z80/src/z8/z8_i2c.c``, etc.
+
+- ``struct i2c_slaveops_s``. Each I2C slave device driver must implement
+ an instance of ``struct i2c_slaveops_s``. That structure defines a call
+ table with the following methods:
+
+- **Binding I2C Slave Drivers**. I2C slave drivers are normally directly
+ accessed by user code, We can read and write to device nodes using posix
+ interfaces.
(nuttx) 01/11: spi: Remove useless restrictions
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 9ffac124658dc631ddc9158e929fbd28429c9dd6
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Thu Oct 26 17:04:46 2023 +0800
spi: Remove useless restrictions
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/spi/spi_bitbang.c | 3 ---
drivers/spi/spi_driver.c | 3 ---
drivers/spi/spi_transfer.c | 3 ---
3 files changed, 9 deletions(-)
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 94b40dfe4c..953cb22af5 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -35,8 +35,6 @@
#include <nuttx/mutex.h>
-#ifdef CONFIG_SPI_BITBANG
-
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -559,4 +557,3 @@ void spi_destroy_bitbang(FAR struct spi_dev_s *dev)
kmm_free(dev);
}
-#endif /* CONFIG_SPI_BITBANG */
diff --git a/drivers/spi/spi_driver.c b/drivers/spi/spi_driver.c
index ec1ae8a90c..23dbad4970 100644
--- a/drivers/spi/spi_driver.c
+++ b/drivers/spi/spi_driver.c
@@ -37,8 +37,6 @@
#include <nuttx/mutex.h>
#include <nuttx/spi/spi_transfer.h>
-#ifdef CONFIG_SPI_DRIVER
-
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -393,4 +391,3 @@ int spi_register(FAR struct spi_dev_s *spi, int bus)
return -ENOMEM;
}
-#endif /* CONFIG_SPI_DRIVER */
diff --git a/drivers/spi/spi_transfer.c b/drivers/spi/spi_transfer.c
index 82d1e70c61..4b93d3148c 100644
--- a/drivers/spi/spi_transfer.c
+++ b/drivers/spi/spi_transfer.c
@@ -33,8 +33,6 @@
#include <nuttx/spi/spi.h>
#include <nuttx/spi/spi_transfer.h>
-#ifdef CONFIG_SPI_EXCHANGE
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -143,4 +141,3 @@ int spi_transfer(FAR struct spi_dev_s *spi, FAR struct spi_sequence_s *seq)
return ret;
}
-#endif /* CONFIG_SPI_EXCHANGE */
(nuttx) 04/11: i2c: Remove useless restrictions
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6114c0b948d4ef379f72960b06a851aa9bc5942c
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Fri Oct 27 19:14:34 2023 +0800
i2c: Remove useless restrictions
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/i2c_driver.c | 3 ---
drivers/i2c/pca9540bdp.c | 3 ---
drivers/i2c/tca9548a.c | 3 ---
3 files changed, 9 deletions(-)
diff --git a/drivers/i2c/i2c_driver.c b/drivers/i2c/i2c_driver.c
index 8e35deb98b..06e7a99ee5 100644
--- a/drivers/i2c/i2c_driver.c
+++ b/drivers/i2c/i2c_driver.c
@@ -37,8 +37,6 @@
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/mutex.h>
-#ifdef CONFIG_I2C_DRIVER
-
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -408,4 +406,3 @@ int i2c_register(FAR struct i2c_master_s *i2c, int bus)
return -ENOMEM;
}
-#endif /* CONFIG_I2C_DRIVER */
diff --git a/drivers/i2c/pca9540bdp.c b/drivers/i2c/pca9540bdp.c
index a83c318279..321635c204 100644
--- a/drivers/i2c/pca9540bdp.c
+++ b/drivers/i2c/pca9540bdp.c
@@ -36,8 +36,6 @@
#include "pca9540bdp.h"
#include <nuttx/i2c/pca9540bdp.h>
-#ifdef CONFIG_I2CMULTIPLEXER_PCA9540BDP
-
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@@ -299,4 +297,3 @@ FAR struct pca9540bdp_dev_s *
return priv;
}
-#endif /* CONFIG_I2CMULTIPLEXER_PCA9540BDP */
diff --git a/drivers/i2c/tca9548a.c b/drivers/i2c/tca9548a.c
index ae2ddfa758..e4ad72228a 100644
--- a/drivers/i2c/tca9548a.c
+++ b/drivers/i2c/tca9548a.c
@@ -36,8 +36,6 @@
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/i2c/tca9548a.h>
-#ifdef CONFIG_I2CMULTIPLEXER_TCA9548A
-
#ifndef CONFIG_TCA9548A_I2C_FREQUENCY
# define CONFIG_TCA9548A_I2C_FREQUENCY 400000
#endif
@@ -409,4 +407,3 @@ FAR struct tca9548a_dev_s *
return priv;
}
-#endif /* CONFIG_I2CMULTIPLEXER_TCA9548A */
(nuttx) 08/11: I2c slave: Add POLLOUT event for notifie slave write success
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4e6f3e936051b0f2bf772c881493bfe8b76beb42
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Wed Dec 20 09:48:56 2023 +0800
I2c slave: Add POLLOUT event for notifie slave write success
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/i2c_slave_driver.c | 41 +++++++++++++++++++++++++++++++++--------
include/nuttx/i2c/i2c_slave.h | 9 ++++++++-
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/i2c_slave_driver.c b/drivers/i2c/i2c_slave_driver.c
index 6403847077..feb69db613 100644
--- a/drivers/i2c/i2c_slave_driver.c
+++ b/drivers/i2c/i2c_slave_driver.c
@@ -91,6 +91,10 @@ struct i2c_slave_driver_s
sem_t wait;
+ /* I2C Slave write flag */
+
+ bool writeable;
+
/* Mutual exclusion */
mutex_t lock;
@@ -359,6 +363,11 @@ static ssize_t i2c_slave_write(FAR struct file *filep,
write_bytes = MIN(buflen, CONFIG_I2C_SLAVE_WRITEBUFSIZE);
memcpy(priv->write_buffer, buffer, write_bytes);
ret = I2CS_WRITE(priv->dev, priv->write_buffer, write_bytes);
+ if (ret >= 0)
+ {
+ priv->writeable = false;
+ }
+
nxmutex_unlock(&priv->lock);
return ret < 0 ? ret : write_bytes;
}
@@ -371,7 +380,7 @@ static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup)
{
FAR struct i2c_slave_driver_s *priv;
- int ret;
+ int ret = OK;
DEBUGASSERT(filep->f_inode->i_private != NULL);
@@ -402,6 +411,11 @@ static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
eventset |= POLLIN;
}
+ if (priv->writeable)
+ {
+ eventset |= POLLOUT;
+ }
+
poll_notify(&priv->fds, 1, eventset);
}
else if (fds->priv != NULL)
@@ -464,26 +478,36 @@ static int i2c_slave_unlink(FAR struct inode *inode)
}
#endif
-static int i2c_slave_callback(FAR void *arg, size_t length)
+static int i2c_slave_callback(FAR void *arg, i2c_slave_complete_t status,
+ size_t length)
{
FAR struct i2c_slave_driver_s *priv = arg;
+ pollevent_t events;
int semcount;
/* Get exclusive access to the I2C Slave driver state structure */
nxmutex_lock(&priv->lock);
- priv->read_index = 0;
- priv->read_length = length;
+ if (status == I2CS_RX_COMPLETE)
+ {
+ events = POLLIN;
+ priv->read_index = 0;
+ priv->read_length = length;
- while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 1)
+ while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 1)
+ {
+ nxsem_post(&priv->wait);
+ }
+ }
+ else
{
- nxsem_post(&priv->wait);
+ events = POLLOUT;
+ priv->writeable = true;
}
nxmutex_unlock(&priv->lock);
-
- poll_notify(&priv->fds, 1, POLLIN);
+ poll_notify(&priv->fds, 1, events);
return OK;
}
@@ -541,6 +565,7 @@ int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
priv->dev = dev;
priv->addr = addr;
priv->nbits = nbits;
+ priv->writeable = true;
ret = I2CS_READ(priv->dev, priv->read_buffer,
CONFIG_I2C_SLAVE_READBUFSIZE);
diff --git a/include/nuttx/i2c/i2c_slave.h b/include/nuttx/i2c/i2c_slave.h
index dd1c6c39c1..2bbaccf618 100644
--- a/include/nuttx/i2c/i2c_slave.h
+++ b/include/nuttx/i2c/i2c_slave.h
@@ -206,9 +206,16 @@
* Public Types
****************************************************************************/
+typedef enum i2c_slave_complete_e
+{
+ I2CS_RX_COMPLETE = 0,
+ I2CS_TX_COMPLETE
+} i2c_slave_complete_t;
+
/* The callback function */
-typedef int (i2c_slave_callback_t)(void *arg, size_t rx_len);
+typedef int (i2c_slave_callback_t)(FAR void *arg, i2c_slave_complete_t state,
+ size_t len);
/* The I2C vtable */
(nuttx) 05/11: Add I2C Slave driver
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit f4a234613e8d4d5b89d6f63adf5d34ec324620f8
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Tue Oct 24 17:14:21 2023 +0800
Add I2C Slave driver
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/CMakeLists.txt | 4 +
drivers/i2c/Kconfig | 24 ++
drivers/i2c/Make.defs | 4 +
drivers/i2c/i2c_slave_driver.c | 523 +++++++++++++++++++++++++++++++++++++++++
include/nuttx/i2c/i2c_slave.h | 27 +++
5 files changed, 582 insertions(+)
diff --git a/drivers/i2c/CMakeLists.txt b/drivers/i2c/CMakeLists.txt
index d3f32ac006..b365491fee 100644
--- a/drivers/i2c/CMakeLists.txt
+++ b/drivers/i2c/CMakeLists.txt
@@ -30,6 +30,10 @@ if(CONFIG_I2C)
list(APPEND SRCS i2c_bitbang.c)
endif()
+ if(CONFIG_I2C_SLAVE_DRIVER)
+ list(APPEND SRCS i2c_slave_driver.c)
+ endif()
+
# Include the selected I2C multiplexer drivers
if(CONFIG_I2CMULTIPLEXER_PCA9540BDP)
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 764fc7473d..a0883f5a20 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -24,6 +24,30 @@ config I2C_SLAVE
bool "I2C Slave"
default n
+menu "I2C Slave Support"
+
+config I2C_SLAVE_DRIVER
+ bool "I2C Slave driver"
+ default n
+ ---help---
+ Enable I2C Slave driver
+
+config I2C_SLAVE_READBUFSIZE
+ int "I2C Slave driver read buffer size"
+ default 32
+ depends on I2C_SLAVE_DRIVER
+ ---help---
+ I2C Slave read buffer size
+
+config I2C_SLAVE_WRITEBUFSIZE
+ int "I2C Slave driver write buffer size"
+ default 32
+ depends on I2C_SLAVE_DRIVER
+ ---help---
+ I2C Slave write buffer size
+
+endmenu # I2C Slave Support
+
config I2C_POLLED
bool "Polled I2C (no interrupts)"
default n
diff --git a/drivers/i2c/Make.defs b/drivers/i2c/Make.defs
index d069ad80dc..e823327de0 100644
--- a/drivers/i2c/Make.defs
+++ b/drivers/i2c/Make.defs
@@ -32,6 +32,10 @@ ifeq ($(CONFIG_I2C_BITBANG),y)
CSRCS += i2c_bitbang.c
endif
+ifeq ($(CONFIG_I2C_SLAVE_DRIVER),y)
+CSRCS += i2c_slave_driver.c
+endif
+
# Include the selected I2C multiplexer drivers
ifeq ($(CONFIG_I2CMULTIPLEXER_PCA9540BDP),y)
diff --git a/drivers/i2c/i2c_slave_driver.c b/drivers/i2c/i2c_slave_driver.c
new file mode 100644
index 0000000000..1cb71262e1
--- /dev/null
+++ b/drivers/i2c/i2c_slave_driver.c
@@ -0,0 +1,523 @@
+/****************************************************************************
+ * drivers/i2c/i2c_slave_driver.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/mutex.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/i2c/i2c_slave.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define DEVNAME_FMT "/dev/i2cslv%d"
+#define DEVNAME_FMTLEN (11 + 3 + 1)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int i2c_slave_open(FAR struct file *filep);
+static int i2c_slave_close(FAR struct file *filep);
+static ssize_t i2c_slave_read(FAR struct file *filep, FAR char *buffer,
+ size_t buflen);
+static ssize_t i2c_slave_write(FAR struct file *filep,
+ FAR const char *buffer, size_t buflen);
+static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup);
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+static int i2c_slave_unlink(FAR struct inode *inode);
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct i2c_slave_driver_s
+{
+ /* Slave private data */
+
+ FAR struct i2c_slave_s *dev;
+
+ /* Slave send buffer */
+
+ uint8_t write_buffer[CONFIG_I2C_SLAVE_WRITEBUFSIZE];
+
+ /* Slave receive buffer */
+
+ uint8_t read_buffer[CONFIG_I2C_SLAVE_READBUFSIZE];
+
+ /* Slave receive buffer length */
+
+ size_t read_length;
+
+ /* Read buffer index */
+
+ size_t read_index;
+
+ /* Wait for transfer to complete */
+
+ sem_t wait;
+
+ /* Mutual exclusion */
+
+ mutex_t lock;
+
+ /* The poll waiter */
+
+ FAR struct pollfd *fds;
+
+ /* Number of open references */
+
+ int16_t crefs;
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+ bool unlinked; /* Indicates if the driver has been unlinked */
+#endif
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct file_operations g_i2cslavefops =
+{
+ i2c_slave_open, /* open */
+ i2c_slave_close, /* close */
+ i2c_slave_read, /* read */
+ i2c_slave_write, /* write */
+ NULL, /* seek */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ NULL, /* truncate */
+ i2c_slave_poll /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+ , i2c_slave_unlink /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: i2c_slave_open
+ *
+ * Description:
+ * This function is called whenever the I2C Slave device is opened.
+ *
+ * Input Parameters:
+ * filep - File structure instance
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success. A negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+static int i2c_slave_open(FAR struct file *filep)
+{
+ FAR struct i2c_slave_driver_s *priv;
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
+
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
+
+ /* Get exclusive access to the I2C Slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+
+ /* Increment the count of open references on the driver */
+
+ priv->crefs++;
+ DEBUGASSERT(priv->crefs > 0);
+
+ nxmutex_unlock(&priv->lock);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: i2c_slave_close
+ *
+ * Description:
+ * This routine is called when the I2C Slave device is closed.
+ *
+ * Input Parameters:
+ * filep - File structure instance
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; A negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+static int i2c_slave_close(FAR struct file *filep)
+{
+ FAR struct i2c_slave_driver_s *priv;
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
+
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
+
+ /* Get exclusive access to the I2C slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+
+ /* Decrement the count of open references on the driver */
+
+ DEBUGASSERT(priv->crefs > 0);
+ priv->crefs--;
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+ if (priv->crefs <= 0 && priv->unlinked)
+ {
+ nxmutex_destroy(&priv->lock);
+ kmm_free(priv);
+ filep->f_inode->i_private = NULL;
+ return OK;
+ }
+#endif
+
+ nxmutex_unlock(&priv->lock);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: i2c_slave_read
+ *
+ * Description:
+ * This routine is called when the application requires to read the data
+ * received by the I2C Slave device.
+ *
+ * Input Parameters:
+ * filep - File structure instance
+ * buffer - User-provided to save the data
+ * buflen - The maximum size of the user-provided buffer
+ *
+ * Returned Value:
+ * The positive non-zero number of bytes read on success, 0 on if an
+ * end-of-file condition, or a negated errno value on any failure.
+ *
+ ****************************************************************************/
+
+static ssize_t i2c_slave_read(FAR struct file *filep, FAR char *buffer,
+ size_t buflen)
+{
+ FAR struct i2c_slave_driver_s *priv;
+ int ret;
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
+
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
+
+ /* Get exclusive access to the I2C Slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+
+ while (priv->read_length == 0)
+ {
+ nxmutex_unlock(&priv->lock);
+ if (filep->f_oflags & O_NONBLOCK)
+ {
+ return -EAGAIN;
+ }
+
+ ret = nxsem_wait(&priv->wait);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ nxmutex_lock(&priv->lock);
+ }
+
+ buflen = MIN(buflen, priv->read_length);
+ memcpy(buffer, priv->read_buffer + priv->read_index, buflen);
+ priv->read_index += buflen;
+ priv->read_length -= buflen;
+ nxmutex_unlock(&priv->lock);
+ return buflen;
+}
+
+/****************************************************************************
+ * Name: i2c_slave_write
+ *
+ * Description:
+ * This routine is called when the application needs to enqueue data to be
+ * transferred at the next leading clock edge of the I2C Slave controller.
+ *
+ * Input Parameters:
+ * filep - Instance of struct file to use with the write
+ * buffer - Data to write
+ * buflen - Length of data to write in bytes
+ *
+ * Returned Value:
+ * On success, the number of bytes written are returned (zero indicates
+ * nothing was written). On any failure, a negated errno value is returned.
+ *
+ ****************************************************************************/
+
+static ssize_t i2c_slave_write(FAR struct file *filep,
+ FAR const char *buffer, size_t buflen)
+{
+ FAR struct i2c_slave_driver_s *priv;
+ size_t write_bytes;
+ int ret;
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
+
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
+
+ /* Get exclusive access to the I2C Slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+
+ write_bytes = MIN(buflen, CONFIG_I2C_SLAVE_WRITEBUFSIZE);
+ memcpy(priv->write_buffer, buffer, write_bytes);
+ ret = I2CS_WRITE(priv->dev, priv->write_buffer, write_bytes);
+ nxmutex_unlock(&priv->lock);
+ return ret < 0 ? ret : write_bytes;
+}
+
+/****************************************************************************
+ * Name: i2c_slave_poll
+ ****************************************************************************/
+
+static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
+ bool setup)
+{
+ FAR struct i2c_slave_driver_s *priv;
+ int ret;
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
+
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
+
+ /* Get exclusive access to the I2C Slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+ if (setup)
+ {
+ pollevent_t eventset = 0;
+
+ if (priv->fds == NULL)
+ {
+ priv->fds = fds;
+ fds->priv = &priv->fds;
+ }
+ else
+ {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (priv->read_length > 0)
+ {
+ eventset |= POLLIN;
+ }
+
+ poll_notify(&priv->fds, 1, eventset);
+ }
+ else if (fds->priv != NULL)
+ {
+ priv->fds = NULL;
+ fds->priv = NULL;
+ }
+
+out:
+ nxmutex_unlock(&priv->lock);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: i2c_slave_unlink
+ *
+ * Description:
+ * This routine is called when the I2C Slave device is unlinked.
+ *
+ * Input Parameters:
+ * inode - The inode associated with the I2C Slave device
+ *
+ * Returned Value:
+ * Zero is returned on success; a negated value is returned on any failure.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+static int i2c_slave_unlink(FAR struct inode *inode)
+{
+ FAR struct i2c_slave_driver_s *priv;
+
+ DEBUGASSERT(inode->i_private != NULL);
+
+ /* Get our private data structure */
+
+ priv = inode->i_private;
+
+ /* Get exclusive access to the I2C Slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+
+ /* Are there open references to the driver data structure? */
+
+ if (priv->crefs <= 0)
+ {
+ nxmutex_destroy(&priv->lock);
+ kmm_free(priv);
+ inode->i_private = NULL;
+ return OK;
+ }
+
+ /* No... just mark the driver as unlinked and free the resources when the
+ * last client closes their reference to the driver.
+ */
+
+ priv->unlinked = true;
+ nxmutex_unlock(&priv->lock);
+ return OK;
+}
+#endif
+
+static int i2c_slave_callback(FAR void *arg, size_t length)
+{
+ FAR struct i2c_slave_driver_s *priv = arg;
+ int semcount;
+
+ /* Get exclusive access to the I2C Slave driver state structure */
+
+ nxmutex_lock(&priv->lock);
+
+ priv->read_index = 0;
+ priv->read_length = length;
+
+ while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 1)
+ {
+ nxsem_post(&priv->wait);
+ }
+
+ nxmutex_unlock(&priv->lock);
+
+ poll_notify(&priv->fds, 1, POLLIN);
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: i2c_slave_register
+ *
+ * Description:
+ * Register the I2C Slave character device driver as 'devpath'.
+ *
+ * Input Parameters:
+ * dev - An instance of the I2C Slave interface to use to communicate
+ * with the I2C Slave device
+ * bus - The I2C Slave bus number. This will be used as the I2C device
+ * minor number. The I2C Slave character device will be
+ * registered as /dev/i2cslvN where N is the minor number
+ * addr - I2C Slave address
+ * nbits - The number of address bits provided (7 or 10)
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
+ int nbits)
+{
+ FAR struct i2c_slave_driver_s *priv;
+ char devname[DEVNAME_FMTLEN];
+ int ret;
+
+ /* Sanity check */
+
+ DEBUGASSERT(dev != NULL && (unsigned int)bus < 1000);
+
+ priv = kmm_zalloc(sizeof(struct i2c_slave_driver_s));
+ if (priv == NULL)
+ {
+ return -ENOMEM;
+ }
+
+ snprintf(devname, DEVNAME_FMTLEN, DEVNAME_FMT, bus);
+ ret = register_driver(devname, &g_i2cslavefops, 0666, priv);
+ if (ret < 0)
+ {
+ kmm_free(priv);
+ return ret;
+ }
+
+ nxsem_init(&priv->wait, 0, 0);
+ nxmutex_init(&priv->lock);
+ priv->dev = dev;
+
+ ret = I2CS_SETOWNADDRESS(priv->dev, addr, nbits);
+ if (ret < 0)
+ {
+ goto out;
+ }
+
+ ret = I2CS_READ(priv->dev, priv->read_buffer,
+ CONFIG_I2C_SLAVE_READBUFSIZE);
+ if (ret < 0)
+ {
+ goto out;
+ }
+
+ ret = I2CS_REGISTERCALLBACK(priv->dev, i2c_slave_callback, priv);
+ if (ret > 0)
+ {
+ return OK;
+ }
+
+out:
+ nxmutex_destroy(&priv->lock);
+ nxsem_destroy(&priv->wait);
+ unregister_driver(devname);
+ kmm_free(priv);
+ return ret;
+}
diff --git a/include/nuttx/i2c/i2c_slave.h b/include/nuttx/i2c/i2c_slave.h
index ef29ab6ced..ee33157958 100644
--- a/include/nuttx/i2c/i2c_slave.h
+++ b/include/nuttx/i2c/i2c_slave.h
@@ -223,6 +223,33 @@ extern "C"
#define EXTERN extern
#endif
+#ifdef CONFIG_I2C_SLAVE_DRIVER
+
+/****************************************************************************
+ * Name: i2c_slave_register
+ *
+ * Description:
+ * Register the I2C Slave character device driver as 'devpath'.
+ *
+ * Input Parameters:
+ * dev - An instance of the I2C Slave interface to use to communicate
+ * with the I2C Slave device
+ * bus - The I2C Slave bus number. This will be used as the I2C device
+ * minor number. The I2C Slave character device will be
+ * registered as /dev/i2cslvN where N is the minor number
+ * addr - I2C Slave address
+ * nbits - The number of address bits provided (7 or 10)
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
+ int nbit);
+
+#endif
+
#undef EXTERN
#if defined(__cplusplus)
}
(nuttx) 03/11: spi: Optimize access to private data
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 2bf13ffbb0751ec654c75599d4ace3cc40237cf4
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Thu Oct 26 15:22:56 2023 +0800
spi: Optimize access to private data
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/spi/spi_driver.c | 31 ++++++++++++++++---------------
drivers/spi/spi_slave_driver.c | 40 ++++++++++++++++++++++------------------
2 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/drivers/spi/spi_driver.c b/drivers/spi/spi_driver.c
index 23dbad4970..0774dcd956 100644
--- a/drivers/spi/spi_driver.c
+++ b/drivers/spi/spi_driver.c
@@ -116,16 +116,16 @@ static const struct file_operations g_spidrvr_fops =
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int spidrvr_open(FAR struct file *filep)
{
- FAR struct inode *inode;
FAR struct spi_driver_s *priv;
int ret;
- /* Get our private data structure */
+ /* Sanity check */
- inode = filep->f_inode;
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
- priv = inode->i_private;
- DEBUGASSERT(priv);
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
/* Get exclusive access to the SPI driver state structure */
@@ -152,16 +152,16 @@ static int spidrvr_open(FAR struct file *filep)
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
static int spidrvr_close(FAR struct file *filep)
{
- FAR struct inode *inode;
FAR struct spi_driver_s *priv;
int ret;
- /* Get our private data structure */
+ /* Sanity check */
- inode = filep->f_inode;
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
- priv = inode->i_private;
- DEBUGASSERT(priv);
+ /* Get our private data structure */
+
+ priv = filep->f_inode->i_private;
/* Get exclusive access to the SPI driver state structure */
@@ -184,6 +184,7 @@ static int spidrvr_close(FAR struct file *filep)
{
nxmutex_destroy(&priv->lock);
kmm_free(priv);
+ filep->f_inode->i_private = NULL;
return OK;
}
@@ -218,19 +219,18 @@ static ssize_t spidrvr_write(FAR struct file *filep, FAR const char *buffer,
static int spidrvr_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
- FAR struct inode *inode;
FAR struct spi_driver_s *priv;
FAR struct spi_sequence_s *seq;
int ret;
+ /* Sanity check */
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
spiinfo("cmd=%d arg=%lu\n", cmd, arg);
/* Get our private data structure */
- inode = filep->f_inode;
-
- priv = inode->i_private;
- DEBUGASSERT(priv);
+ priv = filep->f_inode->i_private;
/* Get exclusive access to the SPI driver state structure */
@@ -305,6 +305,7 @@ static int spidrvr_unlink(FAR struct inode *inode)
{
nxmutex_destroy(&priv->lock);
kmm_free(priv);
+ inode->i_private = NULL;
return OK;
}
diff --git a/drivers/spi/spi_slave_driver.c b/drivers/spi/spi_slave_driver.c
index c80ab1ed39..1e33b4f242 100644
--- a/drivers/spi/spi_slave_driver.c
+++ b/drivers/spi/spi_slave_driver.c
@@ -174,18 +174,17 @@ static const struct spi_slave_devops_s g_spisdev_ops =
static int spi_slave_open(FAR struct file *filep)
{
- FAR struct inode *inode;
FAR struct spi_slave_driver_s *priv;
int ret;
- DEBUGASSERT(filep->f_inode->i_private != NULL);
+ /* Sanity check */
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
spiinfo("filep: %p\n", filep);
/* Get our private data structure */
- inode = filep->f_inode;
- priv = inode->i_private;
+ priv = filep->f_inode->i_private;
/* Get exclusive access to the SPI Slave driver state structure */
@@ -229,18 +228,17 @@ static int spi_slave_open(FAR struct file *filep)
static int spi_slave_close(FAR struct file *filep)
{
- FAR struct inode *inode;
FAR struct spi_slave_driver_s *priv;
int ret;
- DEBUGASSERT(filep->f_inode->i_private != NULL);
+ /* Sanity check */
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
spiinfo("filep: %p\n", filep);
/* Get our private data structure */
- inode = filep->f_inode;
- priv = inode->i_private;
+ priv = filep->f_inode->i_private;
/* Get exclusive access to the SPI Slave driver state structure */
@@ -273,7 +271,7 @@ static int spi_slave_close(FAR struct file *filep)
{
nxmutex_destroy(&priv->lock);
kmm_free(priv);
- inode->i_private = NULL;
+ filep->f_inode->i_private = NULL;
return OK;
}
@@ -302,18 +300,19 @@ static int spi_slave_close(FAR struct file *filep)
static ssize_t spi_slave_read(FAR struct file *filep, FAR char *buffer,
size_t buflen)
{
- FAR struct inode *inode;
FAR struct spi_slave_driver_s *priv;
size_t read_bytes;
size_t remaining_words;
int ret;
+ /* Sanity check */
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
spiinfo("filep=%p buffer=%p buflen=%zu\n", filep, buffer, buflen);
/* Get our private data structure */
- inode = filep->f_inode;
- priv = inode->i_private;
+ priv = filep->f_inode->i_private;
if (buffer == NULL)
{
@@ -394,17 +393,18 @@ static ssize_t spi_slave_read(FAR struct file *filep, FAR char *buffer,
static ssize_t spi_slave_write(FAR struct file *filep,
FAR const char *buffer, size_t buflen)
{
- FAR struct inode *inode;
FAR struct spi_slave_driver_s *priv;
size_t enqueued_bytes;
int ret;
+ /* Sanity check */
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
spiinfo("filep=%p buffer=%p buflen=%zu\n", filep, buffer, buflen);
/* Get our private data structure */
- inode = filep->f_inode;
- priv = inode->i_private;
+ priv = filep->f_inode->i_private;
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
@@ -453,13 +453,15 @@ static int spi_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
bool setup)
{
FAR struct spi_slave_driver_s *priv;
- FAR struct inode *inode;
int ret;
+ /* Sanity check */
+
+ DEBUGASSERT(filep->f_inode->i_private != NULL);
+
/* Get our private data structure */
- inode = filep->f_inode;
- priv = inode->i_private;
+ priv = filep->f_inode->i_private;
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
@@ -525,6 +527,8 @@ static int spi_slave_unlink(FAR struct inode *inode)
FAR struct spi_slave_driver_s *priv;
int ret;
+ /* Sanity check */
+
DEBUGASSERT(inode->i_private != NULL);
/* Get our private data structure */
(nuttx) 10/11: i2c_slave: add poll waiters array
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 75fa94af023b5a01bdff3021ccfe6e41bfdb4a9b
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Mon Dec 25 20:46:06 2023 +0800
i2c_slave: add poll waiters array
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/Kconfig | 7 +++++++
drivers/i2c/i2c_slave_driver.c | 23 +++++++++++++++--------
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index a0883f5a20..dfa74af883 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -46,6 +46,13 @@ config I2C_SLAVE_WRITEBUFSIZE
---help---
I2C Slave write buffer size
+config I2C_SLAVE_NPOLLWAITERS
+ int "Number of i2c slave poll waiters"
+ default 1
+ depends on I2C_SLAVE_DRIVER
+ ---help---
+ Number of waiters to i2c slave poll
+
endmenu # I2C Slave Support
config I2C_POLLED
diff --git a/drivers/i2c/i2c_slave_driver.c b/drivers/i2c/i2c_slave_driver.c
index feb69db613..79ade78f6f 100644
--- a/drivers/i2c/i2c_slave_driver.c
+++ b/drivers/i2c/i2c_slave_driver.c
@@ -101,7 +101,7 @@ struct i2c_slave_driver_s
/* The poll waiter */
- FAR struct pollfd *fds;
+ FAR struct pollfd *fds[CONFIG_I2C_SLAVE_NPOLLWAITERS];
/* Number of open references */
@@ -381,6 +381,7 @@ static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
{
FAR struct i2c_slave_driver_s *priv;
int ret = OK;
+ int i;
DEBUGASSERT(filep->f_inode->i_private != NULL);
@@ -395,12 +396,17 @@ static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
{
pollevent_t eventset = 0;
- if (priv->fds == NULL)
+ for (i = 0; i < CONFIG_I2C_SLAVE_NPOLLWAITERS; i++)
{
- priv->fds = fds;
- fds->priv = &priv->fds;
+ if (!priv->fds[i])
+ {
+ priv->fds[i] = fds;
+ fds->priv = &priv->fds[i];
+ break;
+ }
}
- else
+
+ if (i == CONFIG_I2C_SLAVE_NPOLLWAITERS)
{
ret = -EBUSY;
goto out;
@@ -416,11 +422,12 @@ static int i2c_slave_poll(FAR struct file *filep, FAR struct pollfd *fds,
eventset |= POLLOUT;
}
- poll_notify(&priv->fds, 1, eventset);
+ poll_notify(priv->fds, CONFIG_I2C_SLAVE_NPOLLWAITERS, eventset);
}
else if (fds->priv != NULL)
{
- priv->fds = NULL;
+ struct pollfd **slot = fds->priv;
+ *slot = NULL;
fds->priv = NULL;
}
@@ -507,7 +514,7 @@ static int i2c_slave_callback(FAR void *arg, i2c_slave_complete_t status,
}
nxmutex_unlock(&priv->lock);
- poll_notify(&priv->fds, 1, events);
+ poll_notify(priv->fds, CONFIG_I2C_SLAVE_NPOLLWAITERS, events);
return OK;
}
(nuttx) 07/11: add setup and shutdown for i2c master and slave
Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 20930383158fd62c9b61b02d53a20d2215d81fa9
Author: Shoukui Zhang <zh...@xiaomi.com>
AuthorDate: Thu Nov 23 21:06:50 2023 +0800
add setup and shutdown for i2c master and slave
Signed-off-by: Shoukui Zhang <zh...@xiaomi.com>
---
drivers/i2c/i2c_driver.c | 28 +++++++++++++++++++--
drivers/i2c/i2c_slave_driver.c | 57 ++++++++++++++++++++++++++++++++++++------
include/nuttx/i2c/i2c_master.h | 34 +++++++++++++++++++++++++
include/nuttx/i2c/i2c_slave.h | 34 +++++++++++++++++++++++++
4 files changed, 143 insertions(+), 10 deletions(-)
diff --git a/drivers/i2c/i2c_driver.c b/drivers/i2c/i2c_driver.c
index 06e7a99ee5..1a78a64b2d 100644
--- a/drivers/i2c/i2c_driver.c
+++ b/drivers/i2c/i2c_driver.c
@@ -135,13 +135,25 @@ static int i2cdrvr_open(FAR struct file *filep)
return ret;
}
+ /* I2c master initialize */
+
+ if (priv->i2c->ops->setup != NULL && priv->crefs == 0)
+ {
+ ret = I2C_SETUP(priv->i2c);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
/* Increment the count of open references on the driver */
priv->crefs++;
DEBUGASSERT(priv->crefs > 0);
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
#endif
@@ -171,6 +183,17 @@ static int i2cdrvr_close(FAR struct file *filep)
return ret;
}
+ /* I2c master uninitialize */
+
+ if (priv->i2c->ops->shutdown != NULL && priv->crefs == 1)
+ {
+ ret = I2C_SHUTDOWN(priv->i2c);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
/* Decrement the count of open references on the driver */
DEBUGASSERT(priv->crefs > 0);
@@ -187,8 +210,9 @@ static int i2cdrvr_close(FAR struct file *filep)
return OK;
}
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
#endif
diff --git a/drivers/i2c/i2c_slave_driver.c b/drivers/i2c/i2c_slave_driver.c
index 44160017dd..6403847077 100644
--- a/drivers/i2c/i2c_slave_driver.c
+++ b/drivers/i2c/i2c_slave_driver.c
@@ -103,6 +103,14 @@ struct i2c_slave_driver_s
int16_t crefs;
+ /* I2C Slave address */
+
+ int addr;
+
+ /* The number of address bits provided (7 or 10) */
+
+ int nbits;
+
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
bool unlinked; /* Indicates if the driver has been unlinked */
#endif
@@ -150,6 +158,7 @@ static const struct file_operations g_i2cslavefops =
static int i2c_slave_open(FAR struct file *filep)
{
FAR struct i2c_slave_driver_s *priv;
+ int ret;
DEBUGASSERT(filep->f_inode->i_private != NULL);
@@ -161,13 +170,36 @@ static int i2c_slave_open(FAR struct file *filep)
nxmutex_lock(&priv->lock);
+ /* I2c slave initialize */
+
+ if (priv->dev->ops->setup != NULL && priv->crefs == 0)
+ {
+ ret = I2CS_SETUP(priv->dev);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
+ /* Set i2c slave address */
+
+ ret = I2CS_SETOWNADDRESS(priv->dev, priv->addr, priv->nbits);
+ if (ret < 0)
+ {
+ if (priv->dev->ops->shutdown != NULL)
+ {
+ ret = I2CS_SHUTDOWN(priv->dev);
+ }
+ }
+
/* Increment the count of open references on the driver */
priv->crefs++;
DEBUGASSERT(priv->crefs > 0);
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
/****************************************************************************
@@ -188,6 +220,7 @@ static int i2c_slave_open(FAR struct file *filep)
static int i2c_slave_close(FAR struct file *filep)
{
FAR struct i2c_slave_driver_s *priv;
+ int ret = OK;
DEBUGASSERT(filep->f_inode->i_private != NULL);
@@ -199,6 +232,17 @@ static int i2c_slave_close(FAR struct file *filep)
nxmutex_lock(&priv->lock);
+ /* I2c slave uninitialize */
+
+ if (priv->dev->ops->shutdown != NULL && priv->crefs == 1)
+ {
+ ret = I2CS_SHUTDOWN(priv->dev);
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+
/* Decrement the count of open references on the driver */
DEBUGASSERT(priv->crefs > 0);
@@ -213,8 +257,9 @@ static int i2c_slave_close(FAR struct file *filep)
}
#endif
+out:
nxmutex_unlock(&priv->lock);
- return OK;
+ return ret;
}
/****************************************************************************
@@ -494,12 +539,8 @@ int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
nxsem_init(&priv->wait, 0, 0);
nxmutex_init(&priv->lock);
priv->dev = dev;
-
- ret = I2CS_SETOWNADDRESS(priv->dev, addr, nbits);
- if (ret < 0)
- {
- goto out;
- }
+ priv->addr = addr;
+ priv->nbits = nbits;
ret = I2CS_READ(priv->dev, priv->read_buffer,
CONFIG_I2C_SLAVE_READBUFSIZE);
diff --git a/include/nuttx/i2c/i2c_master.h b/include/nuttx/i2c/i2c_master.h
index 39ba782f8b..da74c9faa2 100644
--- a/include/nuttx/i2c/i2c_master.h
+++ b/include/nuttx/i2c/i2c_master.h
@@ -171,6 +171,38 @@
# define I2C_RESET(d) ((d)->ops->reset(d))
#endif
+/****************************************************************************
+ * Name: I2C_SETUP
+ *
+ * Description:
+ * I2c master initialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2C_SETUP(d) ((d)->ops->setup(d))
+
+/****************************************************************************
+ * Name: I2C_SHUTDOWN
+ *
+ * Description:
+ * I2c master uninitialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2C_SHUTDOWN(d) ((d)->ops->shutdown(d))
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -186,6 +218,8 @@ struct i2c_ops_s
#ifdef CONFIG_I2C_RESET
CODE int (*reset)(FAR struct i2c_master_s *dev);
#endif
+ CODE int (*setup)(FAR struct i2c_master_s *dev);
+ CODE int (*shutdown)(FAR struct i2c_master_s *dev);
};
/* This structure contains the full state of I2C as needed for a specific
diff --git a/include/nuttx/i2c/i2c_slave.h b/include/nuttx/i2c/i2c_slave.h
index ee33157958..dd1c6c39c1 100644
--- a/include/nuttx/i2c/i2c_slave.h
+++ b/include/nuttx/i2c/i2c_slave.h
@@ -170,6 +170,38 @@
#define I2CS_REGISTERCALLBACK(d,c,a) ((d)->ops->registercallback(d,c,a))
+/****************************************************************************
+ * Name: I2CS_SETUP
+ *
+ * Description:
+ * I2c slave initialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2CS_SETUP(d) ((d)->ops->setup(d))
+
+/****************************************************************************
+ * Name: I2CS_SHUTDOWN
+ *
+ * Description:
+ * I2c slave uninitialize.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2CS_SHUTDOWN(d) ((d)->ops->shutdown(d))
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -198,6 +230,8 @@ struct i2c_slaveops_s
int (*registercallback)(FAR struct i2c_slave_s *dev,
i2c_slave_callback_t *callback,
FAR void *arg);
+ int (*setup)(FAR struct i2c_slave_s *dev);
+ int (*shutdown)(FAR struct i2c_slave_s *dev);
};
/* I2C private data. This structure only defines the initial fields of the