I2C: up_i2creset should not be a global function; Now it is an I2C interface method

This commit is contained in:
Gregory Nutt 2016-02-02 11:21:45 -06:00
parent f1a5a6dfc7
commit d2571985ef
16 changed files with 1296 additions and 1018 deletions

View File

@ -314,11 +314,14 @@ static int efm32_i2c1_isr(int irq, void *context);
#endif
#endif /* !CONFIG_I2C_POLLED */
static void efm32_i2c_reset(FAR struct efm32_i2c_priv_s *priv);
static void efm32_i2c_hwreset(FAR struct efm32_i2c_priv_s *priv);
static int efm32_i2c_init(FAR struct efm32_i2c_priv_s *priv);
static int efm32_i2c_deinit(FAR struct efm32_i2c_priv_s *priv);
static int efm32_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int efm32_i2c_reset(FAR struct i2c_master_s *dev);
#endif
#ifdef CONFIG_I2C_TRACE
static const char *efm32_i2c_state_str(int i2c_state);
@ -333,6 +336,9 @@ static const char *efm32_i2c_state_str(int i2c_state);
static const struct i2c_ops_s efm32_i2c_ops =
{
.transfer = efm32_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = efm32_i2c_reset
#endif
};
/* I2C device structures */
@ -1315,14 +1321,14 @@ static int efm32_i2c1_isr(int irq, void *context)
****************************************************************************/
/****************************************************************************
* Name: efm32_i2c_reset
* Name: efm32_i2c_hwreset
*
* Description:
* Reset I2C to same state as after a HW reset.
*
****************************************************************************/
static void efm32_i2c_reset(FAR struct efm32_i2c_priv_s *priv)
static void efm32_i2c_hwreset(FAR struct efm32_i2c_priv_s *priv)
{
efm32_i2c_putreg(priv, EFM32_I2C_CTRL_OFFSET, _I2C_CTRL_RESETVALUE);
efm32_i2c_putreg(priv, EFM32_I2C_CLKDIV_OFFSET, _I2C_CLKDIV_RESETVALUE);
@ -1357,7 +1363,7 @@ static int efm32_i2c_init(FAR struct efm32_i2c_priv_s *priv)
/* Eeset all resgister */
efm32_i2c_reset(priv);
efm32_i2c_hwreset(priv);
/* Configure pins */
@ -1417,7 +1423,7 @@ static int efm32_i2c_deinit(FAR struct efm32_i2c_priv_s *priv)
{
/* Disable I2C */
efm32_i2c_reset(priv);
efm32_i2c_hwreset(priv);
/* Unconfigure GPIO pins */
@ -1594,111 +1600,22 @@ static int efm32_i2c_transfer(FAR struct i2c_master_s *dev,
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_i2cinitialize
/************************************************************************************
* Name: efm32_i2c_reset
*
* Description:
* Initialize one I2C bus
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
****************************************************************************/
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct efm32_i2c_priv_s *priv = NULL;
irqstate_t irqs;
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_EFM32_I2C0
case 0:
priv = (struct efm32_i2c_priv_s *)&efm32_i2c0_priv;
break;
#endif
#ifdef CONFIG_EFM32_I2C1
case 1:
priv = (struct efm32_i2c_priv_s *)&efm32_i2c1_priv;
break;
#endif
default:
return NULL;
}
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
efm32_i2c_sem_init(priv);
efm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/****************************************************************************
* Name: up_i2cuninitialize
* Input Parameters:
* dev - Device-specific state data
*
* Description:
* Uninitialize an I2C bus
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s *dev)
{
FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev;
irqstate_t irqs;
ASSERT(dev);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
efm32_i2c_deinit(priv);
/* Release unused resources */
efm32_i2c_sem_destroy(priv);
return OK;
}
/****************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
****************************************************************************/
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s *dev)
int efm32_i2c_reset(FAR struct i2c_master_s *dev)
{
FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev;
unsigned int clock_count;
@ -1802,4 +1719,99 @@ out:
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_i2cinitialize
*
* Description:
* Initialize one I2C bus
*
****************************************************************************/
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct efm32_i2c_priv_s *priv = NULL;
irqstate_t irqs;
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_EFM32_I2C0
case 0:
priv = (struct efm32_i2c_priv_s *)&efm32_i2c0_priv;
break;
#endif
#ifdef CONFIG_EFM32_I2C1
case 1:
priv = (struct efm32_i2c_priv_s *)&efm32_i2c1_priv;
break;
#endif
default:
return NULL;
}
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
efm32_i2c_sem_init(priv);
efm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/****************************************************************************
* Name: up_i2cuninitialize
*
* Description:
* Uninitialize an I2C bus
*
****************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s *dev)
{
FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev;
irqstate_t irqs;
ASSERT(dev);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
efm32_i2c_deinit(priv);
/* Release unused resources */
efm32_i2c_sem_destroy(priv);
return OK;
}
#endif /* CONFIG_EFM32_I2C0 || CONFIG_EFM32_I2C1 */

View File

@ -132,12 +132,15 @@ static int lpc11_i2c_interrupt(int irq, FAR void *context);
static void lpc11_i2c_timeout(int argc, uint32_t arg, ...);
static void lpc11_i2c_setfrequency(struct lpc11_i2cdev_s *priv,
uint32_t frequency);
static void lpc11_stopnext(struct lpc11_i2cdev_s *priv);
/* I2C device operations */
static int lpc11_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
static void lpc11_stopnext(struct lpc11_i2cdev_s *priv);
#ifdef CONFIG_I2C_RESET
static int lpc11_i2c_reset(FAR struct i2c_master_s * dev);
#endif
/****************************************************************************
* Private Data
@ -156,6 +159,9 @@ static struct lpc11_i2cdev_s g_i2c2dev;
struct i2c_ops_s lpc11_i2c_ops =
{
.transfer = lpc11_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = lpc11_i2c_reset
#endif
};
/****************************************************************************
@ -440,6 +446,27 @@ static int lpc11_i2c_interrupt(int irq, FAR void *context)
return OK;
}
/************************************************************************************
* Name: lpc11_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int lpc11_i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Public Functions
****************************************************************************/
@ -615,19 +642,4 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
return OK;
}
/****************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
****************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_LPC11_I2C0 || CONFIG_LPC11_I2C1 || CONFIG_LPC11_I2C2 */

View File

@ -132,12 +132,15 @@ static int lpc17_i2c_interrupt(int irq, FAR void *context);
static void lpc17_i2c_timeout(int argc, uint32_t arg, ...);
static void lpc17_i2c_setfrequency(struct lpc17_i2cdev_s *priv,
uint32_t frequency);
static void lpc17_stopnext(struct lpc17_i2cdev_s *priv);
/* I2C device operations */
static int lpc17_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
static void lpc17_stopnext(struct lpc17_i2cdev_s *priv);
#ifdef CONFIG_I2C_RESET
static int lpc17_i2c_reset(FAR struct i2c_master_s * dev);
#endif
/****************************************************************************
* Private Data
@ -156,6 +159,9 @@ static struct lpc17_i2cdev_s g_i2c2dev;
struct i2c_ops_s lpc17_i2c_ops =
{
.transfer = lpc17_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = lpc17_i2c_reset
#endif
};
/****************************************************************************
@ -440,6 +446,27 @@ static int lpc17_i2c_interrupt(int irq, FAR void *context)
return OK;
}
/************************************************************************************
* Name: lpc17_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int lpc17_i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Public Functions
****************************************************************************/
@ -620,19 +647,4 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
return OK;
}
/****************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
****************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_LPC17_I2C0 || CONFIG_LPC17_I2C1 || CONFIG_LPC17_I2C2 */

View File

@ -137,12 +137,15 @@ static int lpc2378_i2c_interrupt(int irq, FAR void *context);
static void lpc2378_i2c_timeout(int argc, uint32_t arg, ...);
static void lpc2378_i2c_setfrequency(struct lpc2378_i2cdev_s *priv,
uint32_t frequency);
static void lpc2378_stopnext(struct lpc2378_i2cdev_s *priv);
/* I2C device operations */
static int lpc2378_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
static void lpc2378_stopnext(struct lpc2378_i2cdev_s *priv);
#ifdef CONFIG_I2C_RESET
static int lpc2378_i2c_reset(FAR struct i2c_master_s * dev);
#endif
/****************************************************************************
* Private Data
@ -161,6 +164,9 @@ static struct lpc2378_i2cdev_s g_i2c2dev;
struct i2c_ops_s lpc2378_i2c_ops =
{
.transfer = lpc2378_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = lpc2378_i2c_reset
#endif
};
/****************************************************************************
@ -259,50 +265,7 @@ static void lpc2378_i2c_timeout(int argc, uint32_t arg, ...)
}
/****************************************************************************
* Name: lpc2378_i2c_transfer
*
* Description:
* Perform a sequence of I2C transfers
*
****************************************************************************/
static int lpc2378_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
{
struct lpc2378_i2cdev_s *priv = (struct lpc2378_i2cdev_s *)dev;
int ret;
DEBUGASSERT(dev != NULL && msgs != NULL && count > 0);
/* Get exclusive access to the I2C bus */
sem_wait(&priv->mutex);
/* Set up for the transfer */
priv->wrcnt = 0;
priv->rdcnt = 0;
priv->msgs = msgs;
priv->nmsg = count;
/* Configure the I2C frequency.
* REVISIT: Note that the frequency is set only on the first message.
* This could be extended to support different transfer frequencies for
* each message segment.
*/
lpc2378_i2c_setfrequency(priv, msgs->frequency);
/* Perform the transfer */
ret = lpc2378_i2c_start(priv);
sem_post(&priv->mutex);
return ret;
}
/****************************************************************************
* Name: lpc2378_i2c_interrupt
* Name: lpc2378_stopnext
*
* Description:
* Check if we need to issue STOP at the next message
@ -445,6 +408,70 @@ static int lpc2378_i2c_interrupt(int irq, FAR void *context)
return OK;
}
/****************************************************************************
* Name: lpc2378_i2c_transfer
*
* Description:
* Perform a sequence of I2C transfers
*
****************************************************************************/
static int lpc2378_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
{
struct lpc2378_i2cdev_s *priv = (struct lpc2378_i2cdev_s *)dev;
int ret;
DEBUGASSERT(dev != NULL && msgs != NULL && count > 0);
/* Get exclusive access to the I2C bus */
sem_wait(&priv->mutex);
/* Set up for the transfer */
priv->wrcnt = 0;
priv->rdcnt = 0;
priv->msgs = msgs;
priv->nmsg = count;
/* Configure the I2C frequency.
* REVISIT: Note that the frequency is set only on the first message.
* This could be extended to support different transfer frequencies for
* each message segment.
*/
lpc2378_i2c_setfrequency(priv, msgs->frequency);
/* Perform the transfer */
ret = lpc2378_i2c_start(priv);
sem_post(&priv->mutex);
return ret;
}
/************************************************************************************
* Name: lpc2378_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int lpc2378_i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Public Functions
****************************************************************************/
@ -631,19 +658,4 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
return OK;
}
/****************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
****************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_LPC2378_I2C0 || CONFIG_LPC2378_I2C1 || CONFIG_LPC2378_I2C2 */

View File

@ -114,10 +114,13 @@ static struct lpc31_i2cdev_s i2cdevices[2];
static int i2c_interrupt(int irq, FAR void *context);
static void i2c_progress(struct lpc31_i2cdev_s *priv);
static void i2c_timeout(int argc, uint32_t arg, ...);
static void i2c_reset(struct lpc31_i2cdev_s *priv);
static void i2c_hwreset(struct lpc31_i2cdev_s *priv);
static void i2c_setfrequency(struct lpc31_i2cdev_s *priv, uint32_t frequency);
static int i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int i2c_reset(FAR struct i2c_master_s * dev);
#endif
/****************************************************************************
* Private Data
@ -126,6 +129,9 @@ static int i2c_transfer(FAR struct i2c_master_s *dev,
struct i2c_ops_s lpc31_i2c_ops =
{
.transfer = i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = i2c_reset
#endif
};
/****************************************************************************
@ -169,62 +175,6 @@ static void i2c_setfrequency(struct lpc31_i2cdev_s *priv, uint32_t frequency)
}
}
/****************************************************************************
* Name: i2c_transfer
*
* Description:
* Perform a sequence of I2C transfers
*
****************************************************************************/
static int i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, int count)
{
struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev;
irqstate_t flags;
int ret;
/* Get exclusive access to the I2C bus */
sem_wait(&priv->mutex);
flags = irqsave();
/* Set up for the transfer */
priv->state = I2C_STATE_START;
priv->msgs = msgs;
priv->nmsg = count;
/* Configure the I2C frequency.
* REVISIT: Note that the frequency is set only on the first message.
* This could be extended to support different transfer frequencies for
* each message segment.
*/
i2c_setfrequency(priv, msgs->frequency);
/* Start the transfer */
i2c_progress(priv);
/* Start a watchdog to timeout the transfer if the bus is locked up... */
wd_start(priv->timeout, I2C_TIMEOUT, i2c_timeout, 1, (uint32_t)priv);
/* Wait for the transfer to complete */
while (priv->state != I2C_STATE_DONE)
{
sem_wait(&priv->wait);
}
wd_cancel(priv->timeout);
ret = count - priv->nmsg;
irqrestore(flags);
sem_post(&priv->mutex);
return ret;
}
/****************************************************************************
* Name: i2c_interrupt
*
@ -269,7 +219,7 @@ static void i2c_progress(struct lpc31_i2cdev_s *priv)
{
/* Perform a soft reset */
i2c_reset(priv);
i2c_hwreset(priv);
/* FIXME: automatic retry? */
@ -439,7 +389,7 @@ out:
priv->nmsg++;
}
i2c_reset(priv);
i2c_hwreset(priv);
}
priv->state = I2C_STATE_DONE;
@ -477,7 +427,7 @@ static void i2c_timeout(int argc, uint32_t arg, ...)
/* Soft reset the USB controller */
i2c_reset(priv);
i2c_hwreset(priv);
/* Mark the transfer as finished */
@ -489,14 +439,14 @@ static void i2c_timeout(int argc, uint32_t arg, ...)
}
/****************************************************************************
* Name: i2c_reset
* Name: i2c_hwreset
*
* Description:
* Perform a soft reset of the I2C controller
*
****************************************************************************/
static void i2c_reset(struct lpc31_i2cdev_s *priv)
static void i2c_hwreset(struct lpc31_i2cdev_s *priv)
{
putreg32(I2C_CTRL_RESET, priv->base + LPC31_I2C_CTRL_OFFSET);
@ -506,6 +456,83 @@ static void i2c_reset(struct lpc31_i2cdev_s *priv)
;
}
/****************************************************************************
* Name: i2c_transfer
*
* Description:
* Perform a sequence of I2C transfers
*
****************************************************************************/
static int i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, int count)
{
struct lpc31_i2cdev_s *priv = (struct lpc31_i2cdev_s *) dev;
irqstate_t flags;
int ret;
/* Get exclusive access to the I2C bus */
sem_wait(&priv->mutex);
flags = irqsave();
/* Set up for the transfer */
priv->state = I2C_STATE_START;
priv->msgs = msgs;
priv->nmsg = count;
/* Configure the I2C frequency.
* REVISIT: Note that the frequency is set only on the first message.
* This could be extended to support different transfer frequencies for
* each message segment.
*/
i2c_setfrequency(priv, msgs->frequency);
/* Start the transfer */
i2c_progress(priv);
/* Start a watchdog to timeout the transfer if the bus is locked up... */
wd_start(priv->timeout, I2C_TIMEOUT, i2c_timeout, 1, (uint32_t)priv);
/* Wait for the transfer to complete */
while (priv->state != I2C_STATE_DONE)
{
sem_wait(&priv->wait);
}
wd_cancel(priv->timeout);
ret = count - priv->nmsg;
irqrestore(flags);
sem_post(&priv->mutex);
return ret;
}
/************************************************************************************
* Name: i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Public Functions
****************************************************************************/
@ -540,7 +567,7 @@ struct i2c_master_s *up_i2cinitialize(int port)
/* Soft reset the device */
i2c_reset(priv);
i2c_hwreset(priv);
/* Allocate a watchdog timer */
priv->timeout = wd_create();
@ -571,7 +598,7 @@ void up_i2cuninitalize(struct lpc31_i2cdev_s *priv)
{
/* Disable All Interrupts, soft reset the device */
i2c_reset(priv);
i2c_hwreset(priv);
/* Detach Interrupt Handler */

View File

@ -135,6 +135,9 @@ static void lpc43_i2c_setfrequency(struct lpc43_i2cdev_s *priv,
uint32_t frequency);
static int lpc43_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int lpc43_i2c_reset(FAR struct i2c_master_s * dev);
#endif
/****************************************************************************
* I2C device operations
@ -143,6 +146,9 @@ static int lpc43_i2c_transfer(FAR struct i2c_master_s *dev,
struct i2c_ops_s lpc43_i2c_ops =
{
.transfer = lpc43_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = lpc43_i2c_reset
#endif
};
/****************************************************************************
@ -239,49 +245,6 @@ static void lpc43_i2c_timeout(int argc, uint32_t arg, ...)
irqrestore(flags);
}
/****************************************************************************
* Name: lpc43_i2c_transfer
*
* Description:
* Perform a sequence of I2C transfers
*
****************************************************************************/
static int lpc43_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
{
struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)dev;
int ret;
DEBUGASSERT(dev != NULL);
/* Get exclusive access to the I2C bus */
sem_wait(&priv->mutex);
/* Set up for the transfer */
priv->wrcnt = 0;
priv->rdcnt = 0;
priv->msgs = msgs;
priv->nmsg = count;
/* Configure the I2C frequency.
* REVISIT: Note that the frequency is set only on the first message.
* This could be extended to support different transfer frequencies for
* each message segment.
*/
lpc43_i2c_setfrequency(priv, msgs->frequency);
/* Perform the transfer */
ret = lpc43_i2c_start(priv);
sem_post(&priv->mutex);
return ret;
}
/****************************************************************************
* Name: lpc32_i2c_nextmsg
*
@ -419,6 +382,70 @@ static int lpc43_i2c_interrupt(int irq, FAR void *context)
return OK;
}
/****************************************************************************
* Name: lpc43_i2c_transfer
*
* Description:
* Perform a sequence of I2C transfers
*
****************************************************************************/
static int lpc43_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
{
struct lpc43_i2cdev_s *priv = (struct lpc43_i2cdev_s *)dev;
int ret;
DEBUGASSERT(dev != NULL);
/* Get exclusive access to the I2C bus */
sem_wait(&priv->mutex);
/* Set up for the transfer */
priv->wrcnt = 0;
priv->rdcnt = 0;
priv->msgs = msgs;
priv->nmsg = count;
/* Configure the I2C frequency.
* REVISIT: Note that the frequency is set only on the first message.
* This could be extended to support different transfer frequencies for
* each message segment.
*/
lpc43_i2c_setfrequency(priv, msgs->frequency);
/* Perform the transfer */
ret = lpc43_i2c_start(priv);
sem_post(&priv->mutex);
return ret;
}
/************************************************************************************
* Name: lpc43_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int lpc43_i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Public Functions
****************************************************************************/
@ -552,19 +579,4 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
return OK;
}
/****************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
****************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_LPC43_I2C0 || CONFIG_LPC43_I2C1 */

View File

@ -170,14 +170,14 @@ static inline void twi_putrel(struct twi_dev_s *priv, unsigned int offset,
/* I2C transfer helper functions */
static int twi_wait(struct twi_dev_s *priv);
static int twi_wait(struct twi_dev_s *priv);
static void twi_wakeup(struct twi_dev_s *priv, int result);
static int twi_interrupt(struct twi_dev_s *priv);
static int twi_interrupt(struct twi_dev_s *priv);
#ifdef CONFIG_SAM34_TWI0
static int twi0_interrupt(int irq, FAR void *context);
static int twi0_interrupt(int irq, FAR void *context);
#endif
#ifdef CONFIG_SAM34_TWI1
static int twi1_interrupt(int irq, FAR void *context);
static int twi1_interrupt(int irq, FAR void *context);
#endif
static void twi_timeout(int argc, uint32_t arg, ...);
@ -189,6 +189,9 @@ static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg);
static int twi_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int twi_reset(FAR struct i2c_master_s * dev);
#endif
/* Initialization */
@ -211,6 +214,9 @@ static struct twi_dev_s g_twi1;
struct i2c_ops_s g_twiops =
{
.transfer = twi_transfer
#ifdef CONFIG_I2C_RESET
, .reset = twi_reset
#endif
};
/****************************************************************************
@ -744,6 +750,27 @@ static int twi_transfer(FAR struct i2c_master_s *dev,
return ret;
}
/************************************************************************************
* Name: twi_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int twi_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Initialization
****************************************************************************/

View File

@ -234,6 +234,9 @@ static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg);
static int twi_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int twi_reset(FAR struct i2c_master_s * dev);
#endif
/* Initialization */
@ -307,6 +310,9 @@ static struct twi_dev_s g_twi3;
struct i2c_ops_s g_twiops =
{
.transfer = twi_transfer
#ifdef CONFIG_I2C_RESET
, .reset = twi_reset
#endif
};
/****************************************************************************
@ -889,6 +895,140 @@ static int twi_transfer(FAR struct i2c_master_s *dev,
return ret;
}
/************************************************************************************
* Name: twi_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int twi_reset(FAR struct i2c_master_s *dev)
{
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
unsigned int clockcnt;
unsigned int stretchcnt;
uint32_t sclpin;
uint32_t sdapin;
int ret;
ASSERT(priv);
/* Get exclusive access to the TWI device */
twi_takesem(&priv->exclsem);
/* Disable TWI interrupts */
up_disable_irq(priv->attr->irq);
/* Use PIO configuration to un-wedge the bus.
*
* Reconfigure both pins as open drain outputs with initial output value
* "high" (i.e., floating since these are open-drain outputs).
*/
sclpin = MKI2C_OUTPUT(priv->attr->sclcfg);
sdapin = MKI2C_OUTPUT(priv->attr->sdacfg);
sam_configpio(sclpin);
sam_configpio(sdapin);
/* Peripheral clocking must be enabled in order to read valid data from
* the output pin (clocking is enabled automatically for pins configured
* as inputs).
*/
sam_pio_forceclk(sclpin, true);
sam_pio_forceclk(sdapin, true);
/* Clock the bus until any slaves currently driving it low let it float.
* Reading from the output will return the actual sensed level on the
* SDA pin (not the level that we wrote).
*/
clockcnt = 0;
while (sam_pioread(sdapin) == false)
{
/* Give up if we have tried too hard */
if (clockcnt++ > 10)
{
ret = -ETIMEDOUT;
goto errout_with_lock;
}
/* Sniff to make sure that clock stretching has finished. SCL should
* be floating high here unless something is driving it low.
*
* If the bus never relaxes, the reset has failed.
*/
stretchcnt = 0;
while (sam_pioread(sclpin) == false)
{
/* Give up if we have tried too hard */
if (stretchcnt++ > 10)
{
ret = -EAGAIN;
goto errout_with_lock;
}
up_udelay(10);
}
/* Drive SCL low */
sam_piowrite(sclpin, false);
up_udelay(10);
/* Drive SCL high (floating) again */
sam_piowrite(sclpin, true);
up_udelay(10);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
sam_piowrite(sdapin, false);
up_udelay(10);
sam_piowrite(sclpin, false);
up_udelay(10);
sam_piowrite(sclpin, true);
up_udelay(10);
sam_piowrite(sdapin, true);
up_udelay(10);
/* Clocking is no longer forced */
sam_pio_forceclk(sclpin, false);
sam_pio_forceclk(sdapin, false);
/* Re-initialize the port hardware */
twi_hw_initialize(priv, priv->frequency);
ret = OK;
errout_with_lock:
/* Release our lock on the bus */
twi_givesem(&priv->exclsem);
return ret;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Initialization
****************************************************************************/
@ -1228,131 +1368,4 @@ int up_i2cuninitialize(FAR struct i2c_master_s *dev)
return OK;
}
/************************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s *dev)
{
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
unsigned int clockcnt;
unsigned int stretchcnt;
uint32_t sclpin;
uint32_t sdapin;
int ret;
ASSERT(priv);
/* Get exclusive access to the TWI device */
twi_takesem(&priv->exclsem);
/* Disable TWI interrupts */
up_disable_irq(priv->attr->irq);
/* Use PIO configuration to un-wedge the bus.
*
* Reconfigure both pins as open drain outputs with initial output value
* "high" (i.e., floating since these are open-drain outputs).
*/
sclpin = MKI2C_OUTPUT(priv->attr->sclcfg);
sdapin = MKI2C_OUTPUT(priv->attr->sdacfg);
sam_configpio(sclpin);
sam_configpio(sdapin);
/* Peripheral clocking must be enabled in order to read valid data from
* the output pin (clocking is enabled automatically for pins configured
* as inputs).
*/
sam_pio_forceclk(sclpin, true);
sam_pio_forceclk(sdapin, true);
/* Clock the bus until any slaves currently driving it low let it float.
* Reading from the output will return the actual sensed level on the
* SDA pin (not the level that we wrote).
*/
clockcnt = 0;
while (sam_pioread(sdapin) == false)
{
/* Give up if we have tried too hard */
if (clockcnt++ > 10)
{
ret = -ETIMEDOUT;
goto errout_with_lock;
}
/* Sniff to make sure that clock stretching has finished. SCL should
* be floating high here unless something is driving it low.
*
* If the bus never relaxes, the reset has failed.
*/
stretchcnt = 0;
while (sam_pioread(sclpin) == false)
{
/* Give up if we have tried too hard */
if (stretchcnt++ > 10)
{
ret = -EAGAIN;
goto errout_with_lock;
}
up_udelay(10);
}
/* Drive SCL low */
sam_piowrite(sclpin, false);
up_udelay(10);
/* Drive SCL high (floating) again */
sam_piowrite(sclpin, true);
up_udelay(10);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
sam_piowrite(sdapin, false);
up_udelay(10);
sam_piowrite(sclpin, false);
up_udelay(10);
sam_piowrite(sclpin, true);
up_udelay(10);
sam_piowrite(sdapin, true);
up_udelay(10);
/* Clocking is no longer forced */
sam_pio_forceclk(sclpin, false);
sam_pio_forceclk(sdapin, false);
/* Re-initialize the port hardware */
twi_hw_initialize(priv, priv->frequency);
ret = OK;
errout_with_lock:
/* Release our lock on the bus */
twi_givesem(&priv->exclsem);
return ret;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_SAMA5_TWI0 || ... || CONFIG_SAMA5_TWI3 */

View File

@ -229,6 +229,9 @@ static void twi_startmessage(struct twi_dev_s *priv, struct i2c_msg_s *msg);
static int twi_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int twi_reset(FAR struct i2c_master_s * dev);
#endif
/* Initialization */
@ -287,6 +290,9 @@ static struct twi_dev_s g_twi2;
struct i2c_ops_s g_twiops =
{
.transfer = twi_transfer
#ifdef CONFIG_I2C_RESET
, .reset = twi_reset
#endif
};
/****************************************************************************
@ -916,6 +922,140 @@ static int twi_transfer(FAR struct i2c_master_s *dev,
return ret;
}
/************************************************************************************
* Name: twi_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int twi_reset(FAR struct i2c_master_s *dev)
{
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
unsigned int clockcnt;
unsigned int stretchcnt;
uint32_t sclpin;
uint32_t sdapin;
int ret;
ASSERT(priv);
/* Get exclusive access to the TWIHS device */
twi_takesem(&priv->exclsem);
/* Disable TWIHS interrupts */
up_disable_irq(priv->attr->irq);
/* Use PIO configuration to un-wedge the bus.
*
* Reconfigure both pins as open drain outputs with initial output value
* "high" (i.e., floating since these are open-drain outputs).
*/
sclpin = MKI2C_OUTPUT(priv->attr->sclcfg);
sdapin = MKI2C_OUTPUT(priv->attr->sdacfg);
sam_configgpio(sclpin);
sam_configgpio(sdapin);
/* Peripheral clocking must be enabled in order to read valid data from
* the output pin (clocking is enabled automatically for pins configured
* as inputs).
*/
sam_pio_forceclk(sclpin, true);
sam_pio_forceclk(sdapin, true);
/* Clock the bus until any slaves currently driving it low let it float.
* Reading from the output will return the actual sensed level on the
* SDA pin (not the level that we wrote).
*/
clockcnt = 0;
while (sam_pioread(sdapin) == false)
{
/* Give up if we have tried too hard */
if (clockcnt++ > 10)
{
ret = -ETIMEDOUT;
goto errout_with_lock;
}
/* Sniff to make sure that clock stretching has finished. SCL should
* be floating high here unless something is driving it low.
*
* If the bus never relaxes, the reset has failed.
*/
stretchcnt = 0;
while (sam_pioread(sclpin) == false)
{
/* Give up if we have tried too hard */
if (stretchcnt++ > 10)
{
ret = -EAGAIN;
goto errout_with_lock;
}
up_udelay(10);
}
/* Drive SCL low */
sam_piowrite(sclpin, false);
up_udelay(10);
/* Drive SCL high (floating) again */
sam_piowrite(sclpin, true);
up_udelay(10);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
sam_piowrite(sdapin, false);
up_udelay(10);
sam_piowrite(sclpin, false);
up_udelay(10);
sam_piowrite(sclpin, true);
up_udelay(10);
sam_piowrite(sdapin, true);
up_udelay(10);
/* Clocking is no longer forced */
sam_pio_forceclk(sclpin, false);
sam_pio_forceclk(sdapin, false);
/* Re-initialize the port hardware */
twi_hw_initialize(priv, priv->frequency);
ret = OK;
errout_with_lock:
/* Release our lock on the bus */
twi_givesem(&priv->exclsem);
return ret;
}
#endif /* CONFIG_I2C_RESET */
/****************************************************************************
* Initialization
****************************************************************************/
@ -1256,131 +1396,4 @@ int up_i2cuninitialize(FAR struct i2c_master_s *dev)
return OK;
}
/************************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s *dev)
{
struct twi_dev_s *priv = (struct twi_dev_s *)dev;
unsigned int clockcnt;
unsigned int stretchcnt;
uint32_t sclpin;
uint32_t sdapin;
int ret;
ASSERT(priv);
/* Get exclusive access to the TWIHS device */
twi_takesem(&priv->exclsem);
/* Disable TWIHS interrupts */
up_disable_irq(priv->attr->irq);
/* Use PIO configuration to un-wedge the bus.
*
* Reconfigure both pins as open drain outputs with initial output value
* "high" (i.e., floating since these are open-drain outputs).
*/
sclpin = MKI2C_OUTPUT(priv->attr->sclcfg);
sdapin = MKI2C_OUTPUT(priv->attr->sdacfg);
sam_configgpio(sclpin);
sam_configgpio(sdapin);
/* Peripheral clocking must be enabled in order to read valid data from
* the output pin (clocking is enabled automatically for pins configured
* as inputs).
*/
sam_pio_forceclk(sclpin, true);
sam_pio_forceclk(sdapin, true);
/* Clock the bus until any slaves currently driving it low let it float.
* Reading from the output will return the actual sensed level on the
* SDA pin (not the level that we wrote).
*/
clockcnt = 0;
while (sam_pioread(sdapin) == false)
{
/* Give up if we have tried too hard */
if (clockcnt++ > 10)
{
ret = -ETIMEDOUT;
goto errout_with_lock;
}
/* Sniff to make sure that clock stretching has finished. SCL should
* be floating high here unless something is driving it low.
*
* If the bus never relaxes, the reset has failed.
*/
stretchcnt = 0;
while (sam_pioread(sclpin) == false)
{
/* Give up if we have tried too hard */
if (stretchcnt++ > 10)
{
ret = -EAGAIN;
goto errout_with_lock;
}
up_udelay(10);
}
/* Drive SCL low */
sam_piowrite(sclpin, false);
up_udelay(10);
/* Drive SCL high (floating) again */
sam_piowrite(sclpin, true);
up_udelay(10);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
sam_piowrite(sdapin, false);
up_udelay(10);
sam_piowrite(sclpin, false);
up_udelay(10);
sam_piowrite(sclpin, true);
up_udelay(10);
sam_piowrite(sdapin, true);
up_udelay(10);
/* Clocking is no longer forced */
sam_pio_forceclk(sclpin, false);
sam_pio_forceclk(sdapin, false);
/* Re-initialize the port hardware */
twi_hw_initialize(priv, priv->frequency);
ret = OK;
errout_with_lock:
/* Release our lock on the bus */
twi_givesem(&priv->exclsem);
return ret;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_SAMV7_TWIHS0 || CONFIG_SAMV7_TWIHS1 || CONFIG_SAMV7_TWIHS2 */

View File

@ -339,6 +339,9 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
#ifdef CONFIG_I2C_RESET
static int stm32_i2c_reset(FAR struct i2c_master_s *dev);
#endif
/************************************************************************************
* Private Data
@ -368,6 +371,9 @@ static const char *g_trace_names[] =
static const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = stm32_i2c_reset
#endif
};
/* I2C device structures */
@ -1801,122 +1807,21 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
}
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: up_i2cinitialize
* Name: stm32_i2c_reset
*
* Description:
* Initialize one I2C bus
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
************************************************************************************/
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL;
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
#endif
#if STM32_PCLK1_FREQUENCY < 2000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL;
#endif
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_STM32_I2C1
case 1:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C2
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;
}
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/************************************************************************************
* Name: up_i2cuninitialize
* Input Parameters:
* dev - Device-specific state data
*
* Description:
* Uninitialize an I2C bus
*
************************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s *dev)
{
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
int irqs;
ASSERT(dev);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy(priv);
return OK;
}
/************************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s *dev)
static int stm32_i2c_reset(FAR struct i2c_master_s *dev)
{
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
unsigned int clock_count;
@ -2024,5 +1929,112 @@ out:
}
#endif /* CONFIG_I2C_RESET */
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: stm32_i2cbus_initialize
*
* Description:
* Initialize one I2C bus
*
************************************************************************************/
FAR struct i2c_master_s *stm32_i2cbus_initialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL;
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
#endif
#if STM32_PCLK1_FREQUENCY < 2000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL;
#endif
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_STM32_I2C1
case 1:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C2
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;
}
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/************************************************************************************
* Name: stm32_i2cbus_uninitialize
*
* Description:
* Uninitialize an I2C bus
*
************************************************************************************/
int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev)
{
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
int irqs;
ASSERT(dev);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy(priv);
return OK;
}
#endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F40XX */
#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */

View File

@ -65,5 +65,41 @@
# include "chip/stm32_i2c.h"
#endif
/****************************************************************************
* Name: stm32_i2cbus_initialize
*
* Description:
* Initialize the selected I2C port. And return a unique instance of struct
* struct i2c_master_s. This function may be called to obtain multiple
* instances of the interface, each of which may be set up with a
* different frequency and slave address.
*
* Input Parameter:
* Port number (for hardware that has multiple I2C interfaces)
*
* Returned Value:
* Valid I2C device structure reference on succcess; a NULL on failure
*
****************************************************************************/
FAR struct i2c_master_s *stm32_i2cbus_initialize(int port);
/****************************************************************************
* Name: stm32_i2cbus_uninitialize
*
* Description:
* De-initialize the selected I2C port, and power down the device.
*
* Input Parameter:
* Device structure as returned by the stm32_i2cbus_initialize()
*
* Returned Value:
* OK on success, ERROR when internal reference count mismatch or dev
* points to invalid hardware device.
*
****************************************************************************/
int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev);
#endif /* __ARCH_ARM_SRC_STM32_STM32_I2C_H */

View File

@ -368,6 +368,9 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
#ifdef CONFIG_I2C_RESET
static int stm32_i2c_reset(FAR struct i2c_master_s *dev);
#endif
/************************************************************************************
* Private Data
@ -378,6 +381,9 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
static const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = stm32_i2c_reset
#endif
};
#ifdef CONFIG_STM32_I2C1
@ -2249,122 +2255,21 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
}
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: up_i2cinitialize
* Name: stm32_i2c_reset
*
* Description:
* Initialize one I2C bus
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
************************************************************************************/
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct stm32_i2c_priv_s *priv = NULL;
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
#endif
#if STM32_PCLK1_FREQUENCY < 2000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL;
#endif
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_STM32_I2C1
case 1:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C2
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;
}
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/************************************************************************************
* Name: up_i2cuninitialize
* Input Parameters:
* dev - Device-specific state data
*
* Description:
* Uninitialize an I2C bus
*
************************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s *dev)
{
FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev;
int irqs;
ASSERT(dev);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy(priv);
return OK;
}
/************************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
static int stm32_i2c_reset(FAR struct i2c_master_s * dev)
{
FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev;
unsigned int clock_count;
@ -2469,5 +2374,112 @@ out:
}
#endif /* CONFIG_I2C_RESET */
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: stm32_i2cbus_initialize
*
* Description:
* Initialize one I2C bus
*
************************************************************************************/
FAR struct i2c_master_s *stm32_i2cbus_initialize(int port)
{
struct stm32_i2c_priv_s *priv = NULL;
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
#endif
#if STM32_PCLK1_FREQUENCY < 2000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL;
#endif
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_STM32_I2C1
case 1:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C2
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;
}
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/************************************************************************************
* Name: stm32_i2cbus_uninitialize
*
* Description:
* Uninitialize an I2C bus
*
************************************************************************************/
int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev)
{
FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev;
int irqs;
ASSERT(dev);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy(priv);
return OK;
}
#endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F20XX || CONFIG_STM32_STM32F40XX */
#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */

View File

@ -325,6 +325,9 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv);
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
#ifdef CONFIG_I2C_RESET
static int stm32_i2c_reset(FAR struct i2c_master_s *dev);
#endif
/************************************************************************************
* Private Data
@ -335,6 +338,9 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = stm32_i2c_reset
#endif
};
#ifdef CONFIG_STM32_I2C1
@ -1806,122 +1812,21 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
}
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: up_i2cinitialize
* Name: stm32_i2c_reset
*
* Description:
* Initialize one I2C bus
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
************************************************************************************/
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
#endif
#if STM32_PCLK1_FREQUENCY < 2000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL;
#endif
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_STM32_I2C1
case 1:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C2
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;
}
/* Init private data for the first time, increment refs count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/************************************************************************************
* Name: up_i2cuninitialize
* Input Parameters:
* dev - Device-specific state data
*
* Description:
* Uninitialize an I2C bus
*
************************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s * dev)
{
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
int irqs;
ASSERT(dev);
/* Decrement refs and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy(priv);
return OK;
}
/************************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
static int stm32_i2c_reset(FAR struct i2c_master_s * dev)
{
unsigned int clock_count;
unsigned int stretch_count;
@ -2025,5 +1930,112 @@ out:
}
#endif /* CONFIG_I2C_RESET */
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: stm32_i2cbus_initialize
*
* Description:
* Initialize one I2C bus
*
************************************************************************************/
FAR struct i2c_master_s *stm32_i2cbus_initialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation.
#endif
#if STM32_PCLK1_FREQUENCY < 2000000
# warning STM32_I2C_INIT: Peripheral clock must be at least 2 MHz to support 100 kHz operation.
return NULL;
#endif
/* Get I2C private structure */
switch (port)
{
#ifdef CONFIG_STM32_I2C1
case 1:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c1_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C2
case 2:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c2_priv;
break;
#endif
#ifdef CONFIG_STM32_I2C3
case 3:
priv = (struct stm32_i2c_priv_s *)&stm32_i2c3_priv;
break;
#endif
default:
return NULL;
}
/* Init private data for the first time, increment refs count,
* power-up hardware and configure GPIOs.
*/
irqs = irqsave();
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)priv;
}
/************************************************************************************
* Name: stm32_i2cbus_uninitialize
*
* Description:
* Uninitialize an I2C bus
*
************************************************************************************/
int stm32_i2cbus_uninitialize(FAR struct i2c_master_s * dev)
{
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
int irqs;
ASSERT(dev);
/* Decrement refs and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--priv->refs)
{
irqrestore(irqs);
return OK;
}
irqrestore(irqs);
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy(priv);
return OK;
}
#endif /* CONFIG_STM32_STM32F30XX */
#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */

View File

@ -330,6 +330,9 @@ static int tiva_i2c_uninitialize(struct tiva_i2c_priv_s *priv);
static void tiva_i2c_setclock(struct tiva_i2c_priv_s *priv, uint32_t frequency);
static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
int msgc);
#ifdef CONFIG_I2C_RESET
static int tiva_i2c_reset(FAR struct i2c_master_s *dev);
#endif
/************************************************************************************
* Private Data
@ -340,6 +343,9 @@ static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
static const struct i2c_ops_s tiva_i2c_ops =
{
.transfer = tiva_i2c_transfer
#ifdef CONFIG_I2C_RESET
, .reset = tiva_i2c_reset
#endif
};
#ifdef CONFIG_TIVA_I2C0
@ -1996,6 +2002,130 @@ static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
return ret;
}
/************************************************************************************
* Name: tiva_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int tiva_i2c_reset(FAR struct i2c_master_s * dev)
{
struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev;
unsigned int clock_count;
unsigned int stretch_count;
uint32_t scl_gpio;
uint32_t sda_gpio;
int ret = ERROR;
DEBUGASSERT(priv && priv->config);
i2cvdbg("I2C%d:\n", priv->config->devno);
/* Our caller must own a ref */
ASSERT(priv->refs > 0);
/* Lock out other clients */
tiva_i2c_sem_wait(priv);
/* Un-initialize the port */
tiva_i2c_uninitialize(priv);
/* Use GPIO configuration to un-wedge the bus */
scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin);
sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin);
tiva_configgpio(scl_gpio);
tiva_configgpio(sda_gpio);
/* Let SDA go high */
tiva_gpiowrite(sda_gpio, 1);
/* Clock the bus until any slaves currently driving it let it go. */
clock_count = 0;
while (!tiva_gpioread(sda_gpio))
{
/* Give up if we have tried too hard */
if (clock_count++ > 10)
{
goto out;
}
/* Sniff to make sure that clock stretching has finished.
*
* If the bus never relaxes, the reset has failed.
*/
stretch_count = 0;
while (!tiva_gpioread(scl_gpio))
{
/* Give up if we have tried too hard */
if (stretch_count++ > 10)
{
goto out;
}
up_udelay(10);
}
/* Drive SCL low */
tiva_gpiowrite(scl_gpio, 0);
up_udelay(10);
/* Drive SCL high again */
tiva_gpiowrite(scl_gpio, 1);
up_udelay(10);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
tiva_gpiowrite(sda_gpio, 0);
up_udelay(10);
tiva_gpiowrite(scl_gpio, 0);
up_udelay(10);
tiva_gpiowrite(scl_gpio, 1);
up_udelay(10);
tiva_gpiowrite(sda_gpio, 1);
up_udelay(10);
/* Revert the GPIO configuration. */
tiva_configgpio(MKI2C_INPUT(sda_gpio));
tiva_configgpio(MKI2C_INPUT(scl_gpio));
/* Re-init the port */
tiva_i2c_initialize(priv, priv->frequency);
ret = OK;
out:
/* Release the port for re-use by other clients */
tiva_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */
/************************************************************************************
* Public Functions
************************************************************************************/
@ -2167,122 +2297,4 @@ int up_i2cuninitialize(struct i2c_master_s *dev)
return OK;
}
/************************************************************************************
* Name: up_i2creset
*
* Description:
* Reset an I2C bus
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(struct i2c_master_s *dev)
{
struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev;
unsigned int clock_count;
unsigned int stretch_count;
uint32_t scl_gpio;
uint32_t sda_gpio;
int ret = ERROR;
DEBUGASSERT(priv && priv->config);
i2cvdbg("I2C%d:\n", priv->config->devno);
/* Our caller must own a ref */
ASSERT(priv->refs > 0);
/* Lock out other clients */
tiva_i2c_sem_wait(priv);
/* Un-initialize the port */
tiva_i2c_uninitialize(priv);
/* Use GPIO configuration to un-wedge the bus */
scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin);
sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin);
tiva_configgpio(scl_gpio);
tiva_configgpio(sda_gpio);
/* Let SDA go high */
tiva_gpiowrite(sda_gpio, 1);
/* Clock the bus until any slaves currently driving it let it go. */
clock_count = 0;
while (!tiva_gpioread(sda_gpio))
{
/* Give up if we have tried too hard */
if (clock_count++ > 10)
{
goto out;
}
/* Sniff to make sure that clock stretching has finished.
*
* If the bus never relaxes, the reset has failed.
*/
stretch_count = 0;
while (!tiva_gpioread(scl_gpio))
{
/* Give up if we have tried too hard */
if (stretch_count++ > 10)
{
goto out;
}
up_udelay(10);
}
/* Drive SCL low */
tiva_gpiowrite(scl_gpio, 0);
up_udelay(10);
/* Drive SCL high again */
tiva_gpiowrite(scl_gpio, 1);
up_udelay(10);
}
/* Generate a start followed by a stop to reset slave
* state machines.
*/
tiva_gpiowrite(sda_gpio, 0);
up_udelay(10);
tiva_gpiowrite(scl_gpio, 0);
up_udelay(10);
tiva_gpiowrite(scl_gpio, 1);
up_udelay(10);
tiva_gpiowrite(sda_gpio, 1);
up_udelay(10);
/* Revert the GPIO configuration. */
tiva_configgpio(MKI2C_INPUT(sda_gpio));
tiva_configgpio(MKI2C_INPUT(scl_gpio));
/* Re-init the port */
tiva_i2c_initialize(priv, priv->frequency);
ret = OK;
out:
/* Release the port for re-use by other clients */
tiva_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */
#endif /* CONFIG_TIVA_I2C0 ... CONFIG_TIVA_I2C9 */

View File

@ -99,6 +99,9 @@ static void ez80_i2c_setfrequency(FAR struct ez80_i2cdev_s *priv,
static int ez80_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int ez80_i2c_reset(FAR struct i2c_master_s *dev);
#endif
/****************************************************************************
* Public Function Prototypes
@ -118,6 +121,9 @@ static sem_t g_i2csem; /* Serialize I2C transfers */
const struct i2c_ops_s g_ops =
{
ez80_i2c_transfer
#ifdef CONFIG_I2C_RESET
, ez80_i2c_reset
#endif
};
/****************************************************************************
@ -910,6 +916,27 @@ static int ez80_i2c_transfer(FAR struct i2c_master_s *dev,
return ret;
}
/************************************************************************************
* Name: ez80_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int ez80_i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/z80/src/z8/z8_i2c.c
*
* Copyright(C) 2009, 2011, 2013 Gregory Nutt. All rights reserved.
* Copyright(C) 2009, 2011, 2013, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -94,6 +94,9 @@ static void z8_i2c_setfrequency(FAR struct z8_i2cdev_s *priv,
static int z8_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
#ifdef CONFIG_I2C_RESET
static int z8_i2c_reset(FAR struct i2c_master_s *dev);
#endif
/****************************************************************************
* Public Function Prototypes
@ -113,6 +116,9 @@ static sem_t g_i2csem; /* Serialize I2C transfers */
const struct i2c_ops_s g_ops =
{
z8_i2c_transfer,
#ifdef CONFIG_I2C_RESET
, z8_i2c_reset
#endif
};
/****************************************************************************
@ -593,6 +599,27 @@ static int z8_i2c_transfer(FAR struct i2c_master_s *dev,
return ret;
}
/************************************************************************************
* Name: z8_i2c_reset
*
* Description:
* Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
************************************************************************************/
#ifdef CONFIG_I2C_RESET
static int z8_i2c_reset(FAR struct i2c_master_s * dev)
{
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/