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; sem_t wait;
/* I2C Slave write flag */
bool writeable;
/* Mutual exclusion */ /* Mutual exclusion */
mutex_t lock; 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); write_bytes = MIN(buflen, CONFIG_I2C_SLAVE_WRITEBUFSIZE);
memcpy(priv->write_buffer, buffer, write_bytes); memcpy(priv->write_buffer, buffer, write_bytes);
ret = I2CS_WRITE(priv->dev, priv->write_buffer, write_bytes); ret = I2CS_WRITE(priv->dev, priv->write_buffer, write_bytes);
if (ret >= 0)
{
priv->writeable = false;
}
nxmutex_unlock(&priv->lock); nxmutex_unlock(&priv->lock);
return ret < 0 ? ret : write_bytes; 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) bool setup)
{ {
FAR struct i2c_slave_driver_s *priv; FAR struct i2c_slave_driver_s *priv;
int ret; int ret = OK;
DEBUGASSERT(filep->f_inode->i_private != NULL); 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; eventset |= POLLIN;
} }
if (priv->writeable)
{
eventset |= POLLOUT;
}
poll_notify(&priv->fds, 1, eventset); poll_notify(&priv->fds, 1, eventset);
} }
else if (fds->priv != NULL) else if (fds->priv != NULL)
@ -464,26 +478,36 @@ static int i2c_slave_unlink(FAR struct inode *inode)
} }
#endif #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; FAR struct i2c_slave_driver_s *priv = arg;
pollevent_t events;
int semcount; int semcount;
/* Get exclusive access to the I2C Slave driver state structure */ /* Get exclusive access to the I2C Slave driver state structure */
nxmutex_lock(&priv->lock); nxmutex_lock(&priv->lock);
priv->read_index = 0; if (status == I2CS_RX_COMPLETE)
priv->read_length = length;
while (nxsem_get_value(&priv->wait, &semcount) >= 0 && semcount <= 1)
{ {
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); nxmutex_unlock(&priv->lock);
poll_notify(&priv->fds, 1, events);
poll_notify(&priv->fds, 1, POLLIN);
return OK; return OK;
} }
@ -541,6 +565,7 @@ int i2c_slave_register(FAR struct i2c_slave_s *dev, int bus, int addr,
priv->dev = dev; priv->dev = dev;
priv->addr = addr; priv->addr = addr;
priv->nbits = nbits; priv->nbits = nbits;
priv->writeable = true;
ret = I2CS_READ(priv->dev, priv->read_buffer, ret = I2CS_READ(priv->dev, priv->read_buffer,
CONFIG_I2C_SLAVE_READBUFSIZE); CONFIG_I2C_SLAVE_READBUFSIZE);

View File

@ -206,9 +206,16 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
typedef enum i2c_slave_complete_e
{
I2CS_RX_COMPLETE = 0,
I2CS_TX_COMPLETE
} i2c_slave_complete_t;
/* The callback function */ /* 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 */ /* The I2C vtable */