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 <[email protected]>
AuthorDate: Wed Dec 20 09:48:56 2023 +0800

    I2c slave: Add POLLOUT event for notifie slave write success
    
    Signed-off-by: Shoukui Zhang <[email protected]>
---
 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 */
 

Reply via email to