mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 03:05:40 +08:00
SAMA5 TWI: Add support for I2C readwrite and transfer methods
This commit is contained in:
+280
-68
@@ -137,9 +137,12 @@
|
|||||||
struct twi_dev_s
|
struct twi_dev_s
|
||||||
{
|
{
|
||||||
struct i2c_dev_s dev; /* Generic I2C device */
|
struct i2c_dev_s dev; /* Generic I2C device */
|
||||||
struct i2c_msg_s msg; /* A single message for legacy read/write */
|
struct i2c_msg_s *msg; /* Message list */
|
||||||
uintptr_t base; /* Base address of registers */
|
uintptr_t base; /* Base address of registers */
|
||||||
uint16_t irq; /* IRQ number for this device */
|
uint16_t irq; /* IRQ number for this device */
|
||||||
|
uint16_t address; /* Slave address */
|
||||||
|
uint16_t flags; /* Transfer flags */
|
||||||
|
uint8_t msgc; /* Number of message in the message list */
|
||||||
uint8_t twi; /* TWI peripheral number (for debug output) */
|
uint8_t twi; /* TWI peripheral number (for debug output) */
|
||||||
|
|
||||||
sem_t exclsem; /* Only one thread can access at a time */
|
sem_t exclsem; /* Only one thread can access at a time */
|
||||||
@@ -194,6 +197,10 @@ static int twi2_interrupt(int irq, FAR void *context);
|
|||||||
#endif
|
#endif
|
||||||
static void twi_timeout(int argc, uint32_t arg, ...);
|
static void twi_timeout(int argc, uint32_t arg, ...);
|
||||||
|
|
||||||
|
static int twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg);
|
||||||
|
static int twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg);
|
||||||
|
static int twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg);
|
||||||
|
|
||||||
/* I2C device operations */
|
/* I2C device operations */
|
||||||
|
|
||||||
static uint32_t twi_setfrequency(FAR struct i2c_dev_s *dev,
|
static uint32_t twi_setfrequency(FAR struct i2c_dev_s *dev,
|
||||||
@@ -203,8 +210,8 @@ static int twi_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer,
|
|||||||
int buflen);
|
int buflen);
|
||||||
static int twi_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
|
static int twi_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
|
||||||
#ifdef CONFIG_I2C_WRITEREAD
|
#ifdef CONFIG_I2C_WRITEREAD
|
||||||
static int twi_writeread(FAR struct i2c_dev_s *inst, const uint8_t *buffer,
|
static int twi_writeread(FAR struct i2c_dev_s *inst, const uint8_t *wbuffer,
|
||||||
int buflen, uint8_t *rbuffer, int buflen);
|
int wbuflen, uint8_t *rbuffer, int rbuflen);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_I2C_TRANSFER
|
#ifdef CONFIG_I2C_TRANSFER
|
||||||
static int twi_transfer(FAR struct i2c_dev_s *dev,
|
static int twi_transfer(FAR struct i2c_dev_s *dev,
|
||||||
@@ -433,10 +440,12 @@ static int twi_wait(struct twi_dev_s *priv)
|
|||||||
|
|
||||||
static int twi_interrupt(struct twi_dev_s *priv)
|
static int twi_interrupt(struct twi_dev_s *priv)
|
||||||
{
|
{
|
||||||
|
struct i2c_msg_s *msg;
|
||||||
uint32_t sr;
|
uint32_t sr;
|
||||||
uint32_t imr;
|
uint32_t imr;
|
||||||
uint32_t pending;
|
uint32_t pending;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Retrieve masked interrupt status */
|
/* Retrieve masked interrupt status */
|
||||||
|
|
||||||
@@ -448,14 +457,15 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
|
|
||||||
/* Byte received */
|
/* Byte received */
|
||||||
|
|
||||||
|
msg = priv->msg;
|
||||||
if ((pending & TWI_INT_RXRDY) == TWI_INT_RXRDY)
|
if ((pending & TWI_INT_RXRDY) == TWI_INT_RXRDY)
|
||||||
{
|
{
|
||||||
priv->msg.buffer[priv->xfrd] = twi_getreg(priv, SAM_TWI_RHR_OFFSET);
|
msg->buffer[priv->xfrd] = twi_getreg(priv, SAM_TWI_RHR_OFFSET);
|
||||||
priv->xfrd++;
|
priv->xfrd++;
|
||||||
|
|
||||||
/* Check for transfer complete */
|
/* Check for transfer complete */
|
||||||
|
|
||||||
if (priv->xfrd >= priv->msg.length)
|
if (priv->xfrd >= msg->length)
|
||||||
{
|
{
|
||||||
/* The transfer is complete. Disable the RXRDY interrupt and
|
/* The transfer is complete. Disable the RXRDY interrupt and
|
||||||
* enable the TXCOMP interrupt
|
* enable the TXCOMP interrupt
|
||||||
@@ -467,7 +477,7 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
|
|
||||||
/* Not yet complete, but will the next be the last byte? */
|
/* Not yet complete, but will the next be the last byte? */
|
||||||
|
|
||||||
else if (priv->xfrd == (priv->msg.length - 1))
|
else if (priv->xfrd == (msg->length - 1))
|
||||||
{
|
{
|
||||||
/* Yes, set the stop signal */
|
/* Yes, set the stop signal */
|
||||||
|
|
||||||
@@ -481,7 +491,7 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
{
|
{
|
||||||
/* Transfer finished? */
|
/* Transfer finished? */
|
||||||
|
|
||||||
if (priv->xfrd >= priv->msg.length)
|
if (priv->xfrd >= msg->length)
|
||||||
{
|
{
|
||||||
/* The transfer is complete. Disable the TXRDY interrupt and
|
/* The transfer is complete. Disable the TXRDY interrupt and
|
||||||
* enable the TXCOMP interrupt
|
* enable the TXCOMP interrupt
|
||||||
@@ -501,7 +511,7 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
twi_putreg(priv, SAM_TWI_THR_OFFSET, priv->msg.buffer[priv->xfrd]);
|
twi_putreg(priv, SAM_TWI_THR_OFFSET, msg->buffer[priv->xfrd]);
|
||||||
priv->xfrd++;
|
priv->xfrd++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -511,11 +521,34 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
else if ((pending & TWI_INT_TXCOMP) == TWI_INT_TXCOMP)
|
else if ((pending & TWI_INT_TXCOMP) == TWI_INT_TXCOMP)
|
||||||
{
|
{
|
||||||
twi_putreg(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP);
|
twi_putreg(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP);
|
||||||
priv->result = OK;
|
ret = OK;
|
||||||
|
|
||||||
/* Wake up the waiting thread */
|
/* Is there another messasge to send? */
|
||||||
|
|
||||||
twi_givesem(&priv->waitsem);
|
if (priv->msgc > 1)
|
||||||
|
{
|
||||||
|
/* Yes... start the next message */
|
||||||
|
|
||||||
|
priv->msg++;
|
||||||
|
priv->msgc--;
|
||||||
|
ret = twi_startmessage(priv, priv->msg);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* Wake up the thread with the error indication */
|
||||||
|
|
||||||
|
priv->result = ret;
|
||||||
|
twi_givesem(&priv->waitsem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No.. we made it to the end of the message list with no errors.
|
||||||
|
* Wake up the waiting thread with a success indication.
|
||||||
|
*/
|
||||||
|
|
||||||
|
priv->result = OK;
|
||||||
|
twi_givesem(&priv->waitsem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -562,6 +595,123 @@ static void twi_timeout(int argc, uint32_t arg, ...)
|
|||||||
twi_givesem(&priv->waitsem);
|
twi_givesem(&priv->waitsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Name: twi_startread
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Start the next read message
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
static int twi_startread(struct twi_dev_s *priv, struct i2c_msg_s *msg)
|
||||||
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* This function might be called from the interrupt level */
|
||||||
|
|
||||||
|
flags = irqsave();
|
||||||
|
|
||||||
|
/* Setup for the transfer */
|
||||||
|
|
||||||
|
priv->result = -EBUSY;
|
||||||
|
priv->xfrd = 0;
|
||||||
|
|
||||||
|
/* Set STOP signal if only one byte is sent*/
|
||||||
|
|
||||||
|
if (msg->length == 1)
|
||||||
|
{
|
||||||
|
twi_putreg(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set slave address and number of internal address bytes. */
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_MMR_OFFSET, 0);
|
||||||
|
twi_putreg(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_MREAD | TWI_MMR_DADR(msg->addr));
|
||||||
|
|
||||||
|
/* Set internal address bytes */
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
||||||
|
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
||||||
|
|
||||||
|
/* Enable read interrupt and send the START condition */
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_IER_OFFSET, TWI_INT_RXRDY);
|
||||||
|
|
||||||
|
if ((msg->flags & I2C_M_NORESTART) == 0)
|
||||||
|
{
|
||||||
|
twi_putreg(priv, SAM_TWI_CR_OFFSET, TWI_CR_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = twi_wait(priv);
|
||||||
|
irqrestore(flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Name: twi_startwrite
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Start the next write message
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
static int twi_startwrite(struct twi_dev_s *priv, struct i2c_msg_s *msg)
|
||||||
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* This function might be called from the interrupt level */
|
||||||
|
|
||||||
|
flags = irqsave();
|
||||||
|
|
||||||
|
/* Setup for the transfer */
|
||||||
|
|
||||||
|
priv->result = -EBUSY;
|
||||||
|
priv->xfrd = 0;
|
||||||
|
|
||||||
|
/* Set slave address and number of internal address bytes. */
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_MMR_OFFSET, 0);
|
||||||
|
twi_putreg(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_DADR(msg->addr));
|
||||||
|
|
||||||
|
/* Set internal address bytes. */
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
||||||
|
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
||||||
|
|
||||||
|
/* Write first byte to send.*/
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_THR_OFFSET, msg->buffer[0]);
|
||||||
|
|
||||||
|
/* Enable write interrupt */
|
||||||
|
|
||||||
|
twi_putreg(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXRDY);
|
||||||
|
ret = twi_wait(priv);
|
||||||
|
irqrestore(flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Name: twi_startmessage
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Start the next write message
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
static int twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg)
|
||||||
|
{
|
||||||
|
if ((msg->flags & I2C_M_READ) == 0)
|
||||||
|
{
|
||||||
|
return twi_startread(priv, msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return twi_startwrite(priv, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* I2C device operations
|
* I2C device operations
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -613,8 +763,8 @@ static int twi_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
|
|||||||
|
|
||||||
/* Set the correctly shifted, 7-bit address */
|
/* Set the correctly shifted, 7-bit address */
|
||||||
|
|
||||||
priv->msg.addr = addr << 1;
|
priv->address = addr;
|
||||||
priv->msg.flags = 0 ;
|
priv->flags = (nbits == 10) ? I2C_M_TEN : 0;
|
||||||
|
|
||||||
twi_givesem(&priv->exclsem);
|
twi_givesem(&priv->exclsem);
|
||||||
return OK;
|
return OK;
|
||||||
@@ -632,9 +782,16 @@ static int twi_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
|
|||||||
static int twi_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen)
|
static int twi_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct twi_dev_s *priv = (struct twi_dev_s *) dev;
|
struct twi_dev_s *priv = (struct twi_dev_s *) dev;
|
||||||
uint8_t devaddr;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
struct i2c_msg_s msg =
|
||||||
|
{
|
||||||
|
.addr = priv->address,
|
||||||
|
.flags = priv->flags,
|
||||||
|
.buffer = (uint8_t *)buffer,
|
||||||
|
.length = buflen
|
||||||
|
};
|
||||||
|
|
||||||
i2cvdbg("TWI%d buflen: %d\n", priv->twi, buflen);
|
i2cvdbg("TWI%d buflen: %d\n", priv->twi, buflen);
|
||||||
DEBUGASSERT(dev != NULL);
|
DEBUGASSERT(dev != NULL);
|
||||||
|
|
||||||
@@ -642,33 +799,23 @@ static int twi_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int bufle
|
|||||||
|
|
||||||
twi_takesem(&priv->exclsem);
|
twi_takesem(&priv->exclsem);
|
||||||
|
|
||||||
priv->msg.addr &= ~0x01;
|
/* Initiate the wrte */
|
||||||
priv->msg.buffer = (uint8_t*)buffer;
|
|
||||||
priv->msg.length = buflen;
|
|
||||||
priv->result = -EBUSY;
|
|
||||||
priv->xfrd = 0;
|
|
||||||
|
|
||||||
/* Set slave address and number of internal address bytes. */
|
priv->msg = &msg;
|
||||||
|
priv->msgc = 1;
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_MMR_OFFSET, 0);
|
ret = twi_startwrite(priv, &msg);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
i2cdbg("ERROR: twi_startwrite failed: %d\n", ret);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
devaddr = priv->msg.addr >> 1;
|
/* And wait for the wrtie to complete */
|
||||||
twi_putreg(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_DADR(devaddr));
|
|
||||||
|
|
||||||
/* Set internal address bytes. */
|
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
|
||||||
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
|
||||||
|
|
||||||
/* Write first byte to send.*/
|
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_THR_OFFSET, *buffer);
|
|
||||||
|
|
||||||
/* Enable write interrupt */
|
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXRDY);
|
|
||||||
ret = twi_wait(priv);
|
ret = twi_wait(priv);
|
||||||
|
|
||||||
|
errout:
|
||||||
twi_givesem(&priv->exclsem);
|
twi_givesem(&priv->exclsem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -684,49 +831,41 @@ static int twi_write(FAR struct i2c_dev_s *dev, const uint8_t *buffer, int bufle
|
|||||||
|
|
||||||
static int twi_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
|
static int twi_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct twi_dev_s *priv = (struct twi_dev_s *) dev;
|
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
|
||||||
uint8_t devaddr;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
i2cvdbg(TWI%d "buflen: %d\n", priv->twi, buflen);
|
struct i2c_msg_s msg =
|
||||||
|
{
|
||||||
|
.addr = priv->address,
|
||||||
|
.flags = priv->flags | I2C_M_READ,
|
||||||
|
.buffer = buffer,
|
||||||
|
.length = buflen
|
||||||
|
};
|
||||||
|
|
||||||
DEBUGASSERT(dev != NULL);
|
DEBUGASSERT(dev != NULL);
|
||||||
|
i2cvdbg(TWI%d "buflen: %d\n", priv->twi, buflen);
|
||||||
|
|
||||||
/* Get exclusive access to the device */
|
/* Get exclusive access to the device */
|
||||||
|
|
||||||
twi_takesem(&priv->exclsem);
|
twi_takesem(&priv->exclsem);
|
||||||
|
|
||||||
priv->msg.addr |= 0x01;
|
/* Initiate the read */
|
||||||
priv->msg.buffer = buffer;
|
|
||||||
priv->msg.length = buflen;
|
|
||||||
priv->result = -EBUSY;
|
|
||||||
priv->xfrd = 0;
|
|
||||||
|
|
||||||
/* Set STOP signal if only one byte is sent*/
|
priv->msg = &msg;
|
||||||
|
priv->msgc = 1;
|
||||||
|
|
||||||
if (buflen == 1)
|
ret = twi_startread(priv, &msg);
|
||||||
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
twi_putreg(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP);
|
i2cdbg("ERROR: twi_startread failed: %d\n", ret);
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set slave address and number of internal address bytes. */
|
/* And wait for the read to complete */
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_MMR_OFFSET, 0);
|
|
||||||
|
|
||||||
devaddr = priv->msg.addr >> 1;
|
|
||||||
twi_putreg(priv, SAM_TWI_MMR_OFFSET, TWI_MMR_IADRSZ_NONE | TWI_MMR_MREAD | TWI_MMR_DADR(devaddr));
|
|
||||||
|
|
||||||
/* Set internal address bytes */
|
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
|
||||||
twi_putreg(priv, SAM_TWI_IADR_OFFSET, 0);
|
|
||||||
|
|
||||||
/* Enable read interrupt and send the START codnition */
|
|
||||||
|
|
||||||
twi_putreg(priv, SAM_TWI_IER_OFFSET, TWI_INT_RXRDY);
|
|
||||||
twi_putreg(priv, SAM_TWI_CR_OFFSET, TWI_CR_START);
|
|
||||||
|
|
||||||
ret = twi_wait(priv);
|
ret = twi_wait(priv);
|
||||||
|
|
||||||
|
errout:
|
||||||
twi_givesem(&priv->exclsem);
|
twi_givesem(&priv->exclsem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -739,11 +878,54 @@ static int twi_read(FAR struct i2c_dev_s *dev, uint8_t *buffer, int buflen)
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_I2C_WRITEREAD
|
#ifdef CONFIG_I2C_WRITEREAD
|
||||||
static int twi_writeread(FAR struct i2c_dev_s *inst, const uint8_t *buffer,
|
static int twi_writeread(FAR struct i2c_dev_s *dev, const uint8_t *wbuffer,
|
||||||
int buflen, uint8_t *rbuffer, int buflen)
|
int wbuflen, uint8_t *rbuffer, int rbuflen)
|
||||||
{
|
{
|
||||||
#error Not implemented
|
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
|
||||||
return -ENOSYS;
|
int ret;
|
||||||
|
|
||||||
|
struct i2c_msg_s msgv[2] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.addr = priv->address,
|
||||||
|
.flags = priv->flags,
|
||||||
|
.buffer = (uint8_t *)wbuffer, /* Override const */
|
||||||
|
.length = wbuflen
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.addr = priv->address,
|
||||||
|
.flags = priv->flags | ((rbuflen > 0) ? I2C_M_READ : I2C_M_NORESTART),
|
||||||
|
.buffer = rbuffer,
|
||||||
|
.length = (rbuflen < 0) ? -rbuflen : rbuflen
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DEBUGASSERT(dev != NULL);
|
||||||
|
i2cvdbg(TWI%d "wbuflen: %d rbuflen: %d\n", priv->twi, wbuflen, rbuflen);
|
||||||
|
|
||||||
|
/* Get exclusive access to the device */
|
||||||
|
|
||||||
|
twi_takesem(&priv->exclsem);
|
||||||
|
|
||||||
|
/* Initiate the read */
|
||||||
|
|
||||||
|
priv->msg = msgv;
|
||||||
|
priv->msgc = 2;
|
||||||
|
|
||||||
|
ret = twi_startread(priv, msgv);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
i2cdbg("ERROR: twi_startread failed: %d\n", ret);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And wait for the read to complete */
|
||||||
|
|
||||||
|
ret = twi_wait(priv);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
twi_givesem(&priv->exclsem);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -791,8 +973,35 @@ static int twi_registercallback(FAR struct i2c_dev_s *dev,
|
|||||||
static int twi_transfer(FAR struct i2c_dev_s *dev,
|
static int twi_transfer(FAR struct i2c_dev_s *dev,
|
||||||
FAR struct i2c_msg_s *msgs, int count)
|
FAR struct i2c_msg_s *msgs, int count)
|
||||||
{
|
{
|
||||||
#error Not implemented
|
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
|
||||||
return -ENOSYS;
|
int ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev != NULL);
|
||||||
|
i2cvdbg(TWI%d "count: %d\n", priv->twi, count);
|
||||||
|
|
||||||
|
/* Get exclusive access to the device */
|
||||||
|
|
||||||
|
twi_takesem(&priv->exclsem);
|
||||||
|
|
||||||
|
/* Initiate the message transfer */
|
||||||
|
|
||||||
|
priv->msg = msgs;
|
||||||
|
priv->msgc = count;
|
||||||
|
|
||||||
|
ret = twi_startmessage(priv, msgs);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
i2cdbg("ERROR: twi_startread failed: %d\n", ret);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And wait for the read to complete */
|
||||||
|
|
||||||
|
ret = twi_wait(priv);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
twi_givesem(&priv->exclsem);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1012,6 +1221,9 @@ struct i2c_dev_s *up_i2cinitialize(int bus)
|
|||||||
/* Initialize the device structure */
|
/* Initialize the device structure */
|
||||||
|
|
||||||
priv->dev.ops = &g_twiops;
|
priv->dev.ops = &g_twiops;
|
||||||
|
priv->address = 0;
|
||||||
|
priv->flags = 0;
|
||||||
|
|
||||||
sem_init(&priv->exclsem, 0, 1);
|
sem_init(&priv->exclsem, 0, 1);
|
||||||
sem_init(&priv->waitsem, 0, 0);
|
sem_init(&priv->waitsem, 0, 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user