I2c slave: Add POLLOUT event for notifie slave write success

Signed-off-by: Shoukui Zhang <zhangshoukui@xiaomi.com>
This commit is contained in:
Shoukui Zhang 2023-12-20 09:48:56 +08:00 committed by Alan Carvalho de Assis
parent 2093038315
commit 4e6f3e9360
2 changed files with 42 additions and 10 deletions

View File

@ -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;
while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 1)
if (status == I2CS_RX_COMPLETE)
{
nxsem_post(&priv->wait);
events = POLLIN;
priv->read_index = 0;
priv->read_length = length;
while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 1)
{
nxsem_post(&priv->wait);
}
}
else
{
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);

View File

@ -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 */