EFM32, STM32, and Tiva I2C Drivers: Clean up some kruft that is no longer needed after the last massive I2C interfcase change

This commit is contained in:
Gregory Nutt 2016-02-01 19:51:55 -06:00
parent c9a7d48cb2
commit 30624c8dfa
5 changed files with 319 additions and 547 deletions

View File

@ -72,7 +72,6 @@
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/kmalloc.h>
#include <nuttx/clock.h>
#include <arch/board/board.h>
@ -239,26 +238,27 @@ struct efm32_i2c_config_s
struct efm32_i2c_priv_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
const struct efm32_i2c_config_s *config; /* Port configuration */
int refs; /* Referernce count */
sem_t sem_excl; /* Mutual exclusion semaphore */
int refs; /* Referernce count */
sem_t sem_excl; /* Mutual exclusion semaphore */
#ifndef CONFIG_I2C_POLLED
sem_t sem_isr; /* Interrupt wait semaphore */
sem_t sem_isr; /* Interrupt wait semaphore */
#endif
volatile int8_t result; /* result of transfer */
volatile int8_t result; /* result of transfer */
uint8_t i2c_state; /* i2c state machine */
uint32_t i2c_reg_if; /* Current state of I2Cx_IF register. */
uint32_t i2c_reg_state; /* Current state of I2Cx_STATES register. */
uint8_t i2c_state; /* i2c state machine */
uint32_t i2c_reg_if; /* Current state of I2Cx_IF register. */
uint32_t i2c_reg_state; /* Current state of I2Cx_STATES register. */
int addr; /* Message address */
uint8_t msgc; /* Message count */
struct i2c_msg_s *msgv; /* Message list */
uint8_t *ptr; /* Current message buffer */
int dcnt; /* Current message length */
uint32_t flags; /* Current message flags */
uint32_t frequency; /* Current I2C frequency */
int addr; /* Message address */
uint8_t msgc; /* Message count */
struct i2c_msg_s *msgv; /* Message list */
uint8_t *ptr; /* Current message buffer */
int dcnt; /* Current message length */
uint32_t flags; /* Current message flags */
uint32_t frequency; /* Current I2C frequency */
/* I2C trace support */
@ -272,14 +272,6 @@ struct efm32_i2c_priv_s
#endif
};
/* I2C Device, Instance */
struct efm32_i2c_inst_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
struct efm32_i2c_priv_s *priv; /* Common driver private data structure */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -291,16 +283,16 @@ static inline void efm32_i2c_putreg(FAR struct efm32_i2c_priv_s *priv,
static inline void efm32_i2c_modifyreg(FAR struct efm32_i2c_priv_s *priv,
uint8_t offset, uint32_t clearbits,
uint32_t setbits);
static inline void efm32_i2c_sem_wait(FAR struct i2c_master_s *dev);
static inline void efm32_i2c_sem_wait(FAR struct efm32_i2c_priv_s *priv);
#ifdef CONFIG_EFM32_I2C_DYNTIMEOUT
static useconds_t efm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs);
#endif /* CONFIG_EFM32_I2C_DYNTIMEOUT */
static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv);
static inline void efm32_i2c_sem_post(FAR struct i2c_master_s *dev);
static inline void efm32_i2c_sem_init(FAR struct i2c_master_s *dev);
static inline void efm32_i2c_sem_destroy(FAR struct i2c_master_s *dev);
static inline void efm32_i2c_sem_post(FAR struct efm32_i2c_priv_s *priv);
static inline void efm32_i2c_sem_init(FAR struct efm32_i2c_priv_s *priv);
static inline void efm32_i2c_sem_destroy(FAR struct efm32_i2c_priv_s *priv);
#ifdef CONFIG_I2C_TRACE
static void efm32_i2c_tracereset(FAR struct efm32_i2c_priv_s *priv);
@ -325,8 +317,6 @@ static int efm32_i2c1_isr(int irq, void *context);
static void efm32_i2c_reset(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_process(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
static int efm32_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count);
@ -338,6 +328,13 @@ static const char *efm32_i2c_state_str(int i2c_state);
* Private Data
****************************************************************************/
/* I2C interface */
static const struct i2c_ops_s efm32_i2c_ops =
{
.transfer = efm32_i2c_transfer
};
/* I2C device structures */
#ifdef CONFIG_EFM32_I2C0
@ -356,6 +353,7 @@ static const struct efm32_i2c_config_s efm32_i2c0_config =
static struct efm32_i2c_priv_s efm32_i2c0_priv =
{
.ops = &efm32_i2c_ops,
.config = &efm32_i2c0_config,
.refs = 0,
.result = I2CRESULT_NONE,
@ -383,6 +381,7 @@ static const struct efm32_i2c_config_s efm32_i2c1_config =
static struct efm32_i2c_priv_s efm32_i2c1_priv =
{
.ops = &efm32_i2c_ops,
.config = &efm32_i2c1_config,
.refs = 0,
.result = I2CRESULT_NONE,
@ -394,13 +393,6 @@ static struct efm32_i2c_priv_s efm32_i2c1_priv =
};
#endif
/* Device Structures, Instantiation */
static const struct i2c_ops_s efm32_i2c_ops =
{
.transfer = efm32_i2c_transfer
};
/****************************************************************************
* Private Functions
****************************************************************************/
@ -497,9 +489,9 @@ static const char *efm32_i2c_state_str(int i2c_state)
*
****************************************************************************/
static inline void efm32_i2c_sem_wait(FAR struct i2c_master_s *dev)
static inline void efm32_i2c_sem_wait(FAR struct efm32_i2c_priv_s *priv)
{
while (sem_wait(&((struct efm32_i2c_inst_s *)dev)->priv->sem_excl) != OK)
while (sem_wait(&priv->sem_excl) != OK)
{
ASSERT(errno == EINTR);
}
@ -677,9 +669,9 @@ static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv)
*
****************************************************************************/
static inline void efm32_i2c_sem_post(FAR struct i2c_master_s *dev)
static inline void efm32_i2c_sem_post(FAR struct efm32_i2c_priv_s *priv)
{
sem_post(&((struct efm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_post(&priv->sem_excl);
}
/****************************************************************************
@ -690,11 +682,11 @@ static inline void efm32_i2c_sem_post(FAR struct i2c_master_s *dev)
*
****************************************************************************/
static inline void efm32_i2c_sem_init(FAR struct i2c_master_s *dev)
static inline void efm32_i2c_sem_init(FAR struct efm32_i2c_priv_s *priv)
{
sem_init(&((struct efm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1);
sem_init(&priv->sem_excl, 0, 1);
#ifndef CONFIG_I2C_POLLED
sem_init(&((struct efm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0);
sem_init(&priv->sem_isr, 0, 0);
#endif
}
@ -706,11 +698,11 @@ static inline void efm32_i2c_sem_init(FAR struct i2c_master_s *dev)
*
****************************************************************************/
static inline void efm32_i2c_sem_destroy(FAR struct i2c_master_s *dev)
static inline void efm32_i2c_sem_destroy(FAR struct efm32_i2c_priv_s *priv)
{
sem_destroy(&((struct efm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_destroy(&priv->sem_excl);
#ifndef CONFIG_I2C_POLLED
sem_destroy(&((struct efm32_i2c_inst_s *)dev)->priv->sem_isr);
sem_destroy(&priv->sem_isr);
#endif
}
@ -1450,19 +1442,18 @@ static int efm32_i2c_deinit(FAR struct efm32_i2c_priv_s *priv)
****************************************************************************/
/****************************************************************************
* Name: efm32_i2c_process
* Name: efm32_i2c_transfer
*
* Description:
* Common I2C transfer logic
* Generic I2C transfer function
*
****************************************************************************/
static int efm32_i2c_process(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
static int efm32_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
{
struct efm32_i2c_inst_s *inst = (struct efm32_i2c_inst_s *)dev;
FAR struct efm32_i2c_priv_s *priv = inst->priv;
int errval = 0;
FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev;
int ret = OK;
ASSERT(count);
@ -1473,15 +1464,14 @@ static int efm32_i2c_process(FAR struct i2c_master_s *dev,
/* Ensure that address or flags don't change meanwhile */
efm32_i2c_sem_wait(dev);
efm32_i2c_sem_wait(priv);
/* Reset ptr and dcnt to ensure an unexpected data interrupt doesn't
* overwrite stale data.
*/
priv->dcnt = 0;
priv->ptr = NULL;
priv->ptr = NULL;
priv->msgv = msgs;
priv->msgc = count;
@ -1538,7 +1528,7 @@ static int efm32_i2c_process(FAR struct i2c_master_s *dev,
if (efm32_i2c_sem_waitdone(priv) < 0)
{
errval = ETIMEDOUT;
ret = -ETIMEDOUT;
i2cdbg("Timed out: I2Cx_STATE: 0x%04x I2Cx_STATUS: 0x%08x\n",
efm32_i2c_getreg(priv, EFM32_I2C_STATE_OFFSET),
@ -1557,25 +1547,25 @@ static int efm32_i2c_process(FAR struct i2c_master_s *dev,
/* Arbitration lost during transfer. */
case I2CRESULT_ARBLOST:
errval = EAGAIN;
ret = -EAGAIN;
break;
/* NACK received during transfer. */
case I2CRESULT_NACK:
errval = ENXIO;
ret = -ENXIO;
break;
/* SW fault. */
case I2CRESULT_SWFAULT:
errval = EIO;
ret = -EIO;
break;
/* Usage fault. */
case I2CRESULT_USAGEFAULT:
errval = EINTR;
ret = -EINTR;
break;
/* Bus error during transfer (misplaced START/STOP).
@ -1583,7 +1573,7 @@ static int efm32_i2c_process(FAR struct i2c_master_s *dev,
*/
case I2CRESULT_BUSERR:
errval = EBUSY;
ret = -EBUSY;
break;
}
}
@ -1600,22 +1590,8 @@ static int efm32_i2c_process(FAR struct i2c_master_s *dev,
priv->dcnt = 0;
priv->ptr = NULL;
efm32_i2c_sem_post(dev);
return -errval;
}
/****************************************************************************
* Name: efm32_i2c_transfer
*
* Description:
* Generic I2C transfer function
*
****************************************************************************/
static int efm32_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_msg_s *msgs, int count)
{
return efm32_i2c_process(dev, msgs, count);
efm32_i2c_sem_post(priv);
return ret;
}
/****************************************************************************
@ -1632,9 +1608,7 @@ static int efm32_i2c_transfer(FAR struct i2c_master_s *dev,
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct efm32_i2c_priv_s *priv = NULL; /* Private data of device with multiple
* instances */
struct efm32_i2c_inst_s *inst = NULL; /* Device, single instance */
struct efm32_i2c_priv_s *priv = NULL;
irqstate_t irqs;
/* Get I2C private structure */
@ -1657,18 +1631,6 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
return NULL;
}
/* Allocate instance */
if (!(inst = kmm_malloc(sizeof(struct efm32_i2c_inst_s))))
{
return NULL;
}
/* Initialize instance */
inst->ops = &efm32_i2c_ops;
inst->priv = priv;
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
@ -1677,12 +1639,12 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
if ((volatile int)priv->refs++ == 0)
{
efm32_i2c_sem_init((struct i2c_master_s *)inst);
efm32_i2c_sem_init(priv);
efm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)inst;
return (struct i2c_master_s *)priv;
}
/****************************************************************************
@ -1695,23 +1657,23 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
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 (((struct efm32_i2c_inst_s *)dev)->priv->refs == 0)
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--((struct efm32_i2c_inst_s *)dev)->priv->refs)
if (--priv->refs)
{
irqrestore(irqs);
kmm_free(dev);
return OK;
}
@ -1719,13 +1681,11 @@ int up_i2cuninitialize(FAR struct i2c_master_s *dev)
/* Disable power and other HW resource (GPIO's) */
efm32_i2c_deinit(((struct efm32_i2c_inst_s *)dev)->priv);
efm32_i2c_deinit(priv);
/* Release unused resources */
efm32_i2c_sem_destroy((struct i2c_master_s *)dev);
kmm_free(dev);
efm32_i2c_sem_destroy(priv);
return OK;
}
@ -1740,7 +1700,7 @@ int up_i2cuninitialize(FAR struct i2c_master_s *dev)
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s *dev)
{
struct efm32_i2c_priv_s *priv;
FAR struct efm32_i2c_priv_s *priv = (struct efm32_i2c_priv_s *)dev;
unsigned int clock_count;
unsigned int stretch_count;
uint32_t scl_gpio;
@ -1749,17 +1709,13 @@ int up_i2creset(FAR struct i2c_master_s *dev)
ASSERT(dev);
/* Get I2C private structure */
priv = ((struct efm32_i2c_inst_s *)dev)->priv;
/* Our caller must own a ref */
ASSERT(priv->refs > 0);
/* Lock out other clients */
efm32_i2c_sem_wait(dev);
efm32_i2c_sem_wait(priv);
/* De-init the port */
@ -1841,7 +1797,7 @@ int up_i2creset(FAR struct i2c_master_s *dev)
out:
/* Release the port for re-use by other clients */
efm32_i2c_sem_post(dev);
efm32_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */

View File

@ -85,7 +85,6 @@
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/kmalloc.h>
#include <nuttx/clock.h>
#include <arch/board/board.h>
@ -249,6 +248,7 @@ struct stm32_i2c_config_s
struct stm32_i2c_priv_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
const struct stm32_i2c_config_s *config; /* Port configuration */
int refs; /* Referernce count */
sem_t sem_excl; /* Mutual exclusion semaphore */
@ -278,14 +278,6 @@ struct stm32_i2c_priv_s
uint32_t status; /* End of transfer SR2|SR1 status */
};
/* I2C Device, Instance */
struct stm32_i2c_inst_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
struct stm32_i2c_priv_s *priv; /* Common driver private data structure */
};
/************************************************************************************
* Private Function Prototypes
************************************************************************************/
@ -297,7 +289,7 @@ static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t o
static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv,
uint8_t offset, uint16_t clearbits,
uint16_t setbits);
static inline void stm32_i2c_sem_wait(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv);
#ifdef CONFIG_STM32_I2C_DYNTIMEO
static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs);
@ -305,9 +297,9 @@ static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs);
static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_destroy(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv);
#ifdef CONFIG_I2C_TRACE
static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv);
@ -345,8 +337,6 @@ static int stm32_i2c3_isr(int irq, void *context);
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_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
@ -373,6 +363,13 @@ static const char *g_trace_names[] =
};
#endif
/* I2C interface */
static const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
};
/* I2C device structures */
#ifdef CONFIG_STM32_I2C1
@ -392,6 +389,7 @@ static const struct stm32_i2c_config_s stm32_i2c1_config =
static struct stm32_i2c_priv_s stm32_i2c1_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c1_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -421,6 +419,7 @@ static const struct stm32_i2c_config_s stm32_i2c2_config =
static struct stm32_i2c_priv_s stm32_i2c2_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c2_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -450,6 +449,7 @@ static const struct stm32_i2c_config_s stm32_i2c3_config =
static struct stm32_i2c_priv_s stm32_i2c3_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c3_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -462,13 +462,6 @@ static struct stm32_i2c_priv_s stm32_i2c3_priv =
};
#endif
/* Device Structures, Instantiation */
static const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
};
/************************************************************************************
* Private Functions
************************************************************************************/
@ -524,9 +517,9 @@ static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv,
*
************************************************************************************/
static inline void stm32_i2c_sem_wait(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv)
{
while (sem_wait(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl) != 0)
while (sem_wait(&priv->sem_excl) != 0)
{
ASSERT(errno == EINTR);
}
@ -778,9 +771,9 @@ static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv)
*
************************************************************************************/
static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_post(struct stm32_i2c_priv_s *priv)
{
sem_post(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_post(&priv->sem_excl);
}
/************************************************************************************
@ -791,11 +784,11 @@ static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev)
*
************************************************************************************/
static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv)
{
sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1);
sem_init(&priv->sem_excl, 0, 1);
#ifndef CONFIG_I2C_POLLED
sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0);
sem_init(&priv->sem_isr, 0, 0);
#endif
}
@ -807,11 +800,11 @@ static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev)
*
************************************************************************************/
static inline void stm32_i2c_sem_destroy(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv)
{
sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_destroy(&priv->sem_excl);
#ifndef CONFIG_I2C_POLLED
sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr);
sem_destroy(&priv->sem_isr);
#endif
}
@ -1604,23 +1597,23 @@ static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv)
************************************************************************************/
/************************************************************************************
* Name: stm32_i2c_process
* Name: stm32_i2c_transfer
*
* Description:
* Common I2C transfer logic
* Generic I2C transfer function
*
************************************************************************************/
static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
{
struct stm32_i2c_inst_s *inst = (struct stm32_i2c_inst_s *)dev;
FAR struct stm32_i2c_priv_s *priv = inst->priv;
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
stm32_i2c_sem_wait(priv); /* Ensure that address or flags don't change meanwhile */
uint32_t status = 0;
#ifdef I2C1_FSMC_CONFLICT
uint32_t ahbenr;
#endif
int errval = 0;
int ret = 0;
ASSERT(count);
@ -1689,7 +1682,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
if (stm32_i2c_sem_waitdone(priv) < 0)
{
status = stm32_i2c_getstatus(priv);
errval = ETIMEDOUT;
ret = -ETIMEDOUT;
i2cdbg("Timed out: CR1: 0x%04x status: 0x%08x\n",
stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET), status);
@ -1723,37 +1716,37 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* Bus Error */
errval = EIO;
ret = -EIO;
}
else if (status & I2C_SR1_ARLO)
{
/* Arbitration Lost (master mode) */
errval = EAGAIN;
ret = -EAGAIN;
}
else if (status & I2C_SR1_AF)
{
/* Acknowledge Failure */
errval = ENXIO;
ret = -ENXIO;
}
else if (status & I2C_SR1_OVR)
{
/* Overrun/Underrun */
errval = EIO;
ret = -EIO;
}
else if (status & I2C_SR1_PECERR)
{
/* PEC Error in reception */
errval = EPROTO;
ret = -EPROTO;
}
else if (status & I2C_SR1_TIMEOUT)
{
/* Timeout or Tlow Error */
errval = ETIME;
ret = -ETIME;
}
/* This is not an error and should never happen since SMBus is not enabled */
@ -1764,7 +1757,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
* that want to trade their ability to master for a pin.
*/
errval = EINTR;
ret = -EINTR;
}
}
@ -1778,7 +1771,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* I2C Bus is for some reason busy */
errval = EBUSY;
ret = -EBUSY;
}
/* Dump the trace result */
@ -1803,24 +1796,8 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
priv->dcnt = 0;
priv->ptr = NULL;
stm32_i2c_sem_post(dev);
return -errval;
}
/************************************************************************************
* Name: stm32_i2c_transfer
*
* Description:
* Generic I2C transfer function
*
************************************************************************************/
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
{
stm32_i2c_sem_wait(dev); /* Ensure that address or flags don't change meanwhile */
return stm32_i2c_process(dev, msgs, count);
stm32_i2c_sem_post(priv);
return ret;
}
/************************************************************************************
@ -1837,8 +1814,7 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL; /* Private data of device with multiple instances */
struct stm32_i2c_inst_s * inst = NULL; /* Device, single instance */
struct stm32_i2c_priv_s * priv = NULL;
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
@ -1873,18 +1849,6 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
return NULL;
}
/* Allocate instance */
if (!(inst = kmm_malloc(sizeof(struct stm32_i2c_inst_s))))
{
return NULL;
}
/* Initialize instance */
inst->ops = &stm32_i2c_ops;
inst->priv = priv;
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
@ -1893,12 +1857,12 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init((struct i2c_master_s *)inst);
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)inst;
return (struct i2c_master_s *)priv;
}
/************************************************************************************
@ -1909,25 +1873,25 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
*
************************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s * dev)
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 (((struct stm32_i2c_inst_s *)dev)->priv->refs == 0)
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--((struct stm32_i2c_inst_s *)dev)->priv->refs)
if (--priv->refs)
{
irqrestore(irqs);
kmm_free(dev);
return OK;
}
@ -1935,13 +1899,11 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(((struct stm32_i2c_inst_s *)dev)->priv);
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy((struct i2c_master_s *)dev);
kmm_free(dev);
stm32_i2c_sem_destroy(priv);
return OK;
}
@ -1954,9 +1916,9 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
************************************************************************************/
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
int up_i2creset(FAR struct i2c_master_s *dev)
{
struct stm32_i2c_priv_s * priv;
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
unsigned int clock_count;
unsigned int stretch_count;
uint32_t scl_gpio;
@ -1965,17 +1927,13 @@ int up_i2creset(FAR struct i2c_master_s * dev)
ASSERT(dev);
/* Get I2C private structure */
priv = ((struct stm32_i2c_inst_s *)dev)->priv;
/* Our caller must own a ref */
ASSERT(priv->refs > 0);
/* Lock out other clients */
stm32_i2c_sem_wait(dev);
stm32_i2c_sem_wait(priv);
/* De-init the port */
@ -2061,7 +2019,7 @@ out:
/* Release the port for re-use by other clients */
stm32_i2c_sem_post(dev);
stm32_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */

View File

@ -92,7 +92,6 @@
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/kmalloc.h>
#include <nuttx/clock.h>
#include <arch/board/board.h>
@ -276,6 +275,7 @@ struct stm32_i2c_config_s
struct stm32_i2c_priv_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
const struct stm32_i2c_config_s *config; /* Port configuration */
int refs; /* Referernce count */
sem_t sem_excl; /* Mutual exclusion semaphore */
@ -307,14 +307,6 @@ struct stm32_i2c_priv_s
uint32_t status; /* End of transfer SR2|SR1 status */
};
/* I2C Device, Instance */
struct stm32_i2c_inst_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
struct stm32_i2c_priv_s *priv; /* Common driver private data structure */
};
/************************************************************************************
* Private Function Prototypes
************************************************************************************/
@ -326,7 +318,7 @@ static inline void stm32_i2c_putreg(FAR struct stm32_i2c_priv_s *priv, uint8_t o
static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv,
uint8_t offset, uint16_t clearbits,
uint16_t setbits);
static inline void stm32_i2c_sem_wait(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv);
#ifdef CONFIG_STM32_I2C_DYNTIMEO
static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs);
@ -334,9 +326,9 @@ static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs);
static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_destroy(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv);
#ifdef CONFIG_I2C_TRACE
static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv);
@ -374,8 +366,6 @@ static int stm32_i2c3_isr(int irq, void *context);
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_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
@ -383,6 +373,13 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
* Private Data
************************************************************************************/
/* I2C interface */
static const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
};
#ifdef CONFIG_STM32_I2C1
static const struct stm32_i2c_config_s stm32_i2c1_config =
{
@ -400,6 +397,7 @@ static const struct stm32_i2c_config_s stm32_i2c1_config =
static struct stm32_i2c_priv_s stm32_i2c1_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c1_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -429,6 +427,7 @@ static const struct stm32_i2c_config_s stm32_i2c2_config =
static struct stm32_i2c_priv_s stm32_i2c2_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c2_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -458,6 +457,7 @@ static const struct stm32_i2c_config_s stm32_i2c3_config =
static struct stm32_i2c_priv_s stm32_i2c3_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c3_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -470,13 +470,6 @@ static struct stm32_i2c_priv_s stm32_i2c3_priv =
};
#endif
/* Device Structures, Instantiation */
static const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
};
/************************************************************************************
* Private Functions
************************************************************************************/
@ -532,9 +525,9 @@ static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv,
*
************************************************************************************/
static inline void stm32_i2c_sem_wait(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv)
{
while (sem_wait(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl) != 0)
while (sem_wait(&priv->sem_excl) != 0)
{
ASSERT(errno == EINTR);
}
@ -786,9 +779,9 @@ static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv)
*
************************************************************************************/
static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv)
{
sem_post(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_post(&priv->sem_excl);
}
/************************************************************************************
@ -799,11 +792,11 @@ static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev)
*
************************************************************************************/
static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv)
{
sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1);
sem_init(&priv->sem_excl, 0, 1);
#ifndef CONFIG_I2C_POLLED
sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0);
sem_init(&priv->sem_isr, 0, 0);
#endif
}
@ -815,11 +808,11 @@ static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev)
*
************************************************************************************/
static inline void stm32_i2c_sem_destroy(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv)
{
sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_destroy(&priv->sem_excl);
#ifndef CONFIG_I2C_POLLED
sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr);
sem_destroy(&priv->sem_isr);
#endif
}
@ -1236,7 +1229,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
* Message handling should only operate when a message has been completely
* sent and after the ISR had the chance to run to set bits after the last
* written/read byte, i.e. priv->dcnt == -1. This is also the case in when
* the ISR is called for the first time. This can seen in stm32_i2c_process()
* the ISR is called for the first time. This can seen in stm32_i2c_transfer()
* before entering the stm32_i2c_sem_waitdone() waiting process.
*
* Message handling should only operate when:
@ -1247,7 +1240,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
* handling dcnt = -1).
*
* When the ISR is called for the first time the same conditions hold.
* This can seen in stm32_i2c_process() before entering the
* This can seen in stm32_i2c_transfer() before entering the
* stm32_i2c_sem_waitdone() waiting process.
*/
@ -1419,7 +1412,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
*
* To be safe in the case of a timeout/NACKed address a stop bit
* is set on the bus to clear it. In POLLED operation it's done
* stm32_i2c_process() after the call to stm32_i2c_sem_waitdone().
* stm32_i2c_transfer() after the call to stm32_i2c_sem_waitdone().
*
* In ISR driven operation the stop bit in case of a NACKed address
* is set in the ISR itself.
@ -1848,7 +1841,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
/* Messages handling(2/2)
*
* Transmission of the whole message chain has been completed. We have to
* terminate the ISR and wake up stm32_i2c_process() that is waiting for
* terminate the ISR and wake up stm32_i2c_transfer() that is waiting for
* the ISR cycle to handle the sending/receiving of the messages.
*/
@ -2035,25 +2028,28 @@ static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv)
************************************************************************************/
/************************************************************************************
* Name: stm32_i2c_process
* Name: stm32_i2c_transfer
*
* Description:
* Common I2C transfer logic
* Generic I2C transfer function
*
************************************************************************************/
static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
{
struct stm32_i2c_inst_s *inst = (struct stm32_i2c_inst_s *)dev;
FAR struct stm32_i2c_priv_s *priv = inst->priv;
uint32_t status = 0;
FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev;
uint32_t status = 0;
#ifdef I2C1_FSMC_CONFLICT
uint32_t ahbenr;
uint32_t ahbenr;
#endif
int errval = 0;
int ret = 0;
ASSERT(count);
DEBUGASSERT(dev != NULL && msgs != NULL && count > 0);
/* Ensure that address or flags don't change meanwhile */
stm32_i2c_sem_wait(priv);
#ifdef I2C1_FSMC_CONFLICT
/* Disable FSMC that shares a pin with I2C1 (LBAR) */
@ -2117,7 +2113,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
if (stm32_i2c_sem_waitdone(priv) < 0)
{
status = stm32_i2c_getstatus(priv);
errval = ETIMEDOUT;
ret = -ETIMEDOUT;
i2cdbg("Timed out: CR1: 0x%04x status: 0x%08x\n",
stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET), status);
@ -2141,7 +2137,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
*
* To be safe in the case of a timeout/NACKed address a stop bit
* is set on the bus to clear it. In POLLED operation it's done
* stm32_i2c_process() after the call to stm32_i2c_sem_waitdone().
* stm32_i2c_transfer() after the call to stm32_i2c_sem_waitdone().
*
* In ISR driven operation the stop bit in case of a NACKed address
* is set in the ISR itself.
@ -2173,37 +2169,37 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* Bus Error */
errval = EIO;
ret = -EIO;
}
else if (status & I2C_SR1_ARLO)
{
/* Arbitration Lost (master mode) */
errval = EAGAIN;
ret = -EAGAIN;
}
else if (status & I2C_SR1_AF)
{
/* Acknowledge Failure */
errval = ENXIO;
ret = -ENXIO;
}
else if (status & I2C_SR1_OVR)
{
/* Overrun/Underrun */
errval = EIO;
ret = -EIO;
}
else if (status & I2C_SR1_PECERR)
{
/* PEC Error in reception */
errval = EPROTO;
ret = -EPROTO;
}
else if (status & I2C_SR1_TIMEOUT)
{
/* Timeout or Tlow Error */
errval = ETIME;
ret = -ETIME;
}
/* This is not an error and should never happen since SMBus is not enabled */
@ -2214,7 +2210,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
* that want to trade their ability to master for a pin.
*/
errval = EINTR;
ret = -EINTR;
}
}
@ -2228,7 +2224,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* I2C Bus is for some reason busy */
errval = EBUSY;
ret = -EBUSY;
}
/* Dump the trace result */
@ -2247,24 +2243,9 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
stm32_i2c_enablefsmc(ahbenr);
#endif
stm32_i2c_sem_post(dev);
return -errval;
}
/************************************************************************************
* Name: stm32_i2c_transfer
*
* Description:
* Generic I2C transfer function
*
************************************************************************************/
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
{
stm32_i2c_sem_wait(dev); /* Ensure that address or flags don't change meanwhile */
return stm32_i2c_process(dev, msgs, count);
stm32_i2c_sem_post(priv);
return ret;
}
/************************************************************************************
@ -2281,8 +2262,7 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL; /* Private data of device with multiple instances */
struct stm32_i2c_inst_s * inst = NULL; /* Device, single instance */
struct stm32_i2c_priv_s *priv = NULL;
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
@ -2317,18 +2297,6 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
return NULL;
}
/* Allocate instance */
if (!(inst = kmm_malloc(sizeof(struct stm32_i2c_inst_s))))
{
return NULL;
}
/* Initialize instance */
inst->ops = &stm32_i2c_ops;
inst->priv = priv;
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
*/
@ -2337,12 +2305,12 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init((struct i2c_master_s *)inst);
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)inst;
return (struct i2c_master_s *)priv;
}
/************************************************************************************
@ -2353,25 +2321,25 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
*
************************************************************************************/
int up_i2cuninitialize(FAR struct i2c_master_s * dev)
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 (((struct stm32_i2c_inst_s *)dev)->priv->refs == 0)
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--((struct stm32_i2c_inst_s *)dev)->priv->refs)
if (--priv->refs)
{
irqrestore(irqs);
kmm_free(dev);
return OK;
}
@ -2379,13 +2347,11 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(((struct stm32_i2c_inst_s *)dev)->priv);
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy((struct i2c_master_s *)dev);
kmm_free(dev);
stm32_i2c_sem_destroy(priv);
return OK;
}
@ -2400,7 +2366,7 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
{
struct stm32_i2c_priv_s * priv;
FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)dev;
unsigned int clock_count;
unsigned int stretch_count;
uint32_t scl_gpio;
@ -2409,17 +2375,13 @@ int up_i2creset(FAR struct i2c_master_s * dev)
ASSERT(dev);
/* Get I2C private structure */
priv = ((struct stm32_i2c_inst_s *)dev)->priv;
/* Our caller must own a ref */
ASSERT(priv->refs > 0);
/* Lock out other clients */
stm32_i2c_sem_wait(dev);
stm32_i2c_sem_wait(priv);
/* De-init the port */
@ -2502,7 +2464,7 @@ out:
/* Release the port for re-use by other clients */
stm32_i2c_sem_post(dev);
stm32_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */

View File

@ -86,7 +86,6 @@
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/kmalloc.h>
#include <nuttx/clock.h>
#include <arch/board/board.h>
@ -241,6 +240,7 @@ struct stm32_i2c_config_s
struct stm32_i2c_priv_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
const struct stm32_i2c_config_s *config; /* Port configuration */
int refs; /* Referernce count */
sem_t sem_excl; /* Mutual exclusion semaphore */
@ -271,14 +271,6 @@ struct stm32_i2c_priv_s
uint32_t status; /* End of transfer SR2|SR1 status */
};
/* I2C Device, Instance */
struct stm32_i2c_inst_s
{
struct i2c_ops_s *ops; /* Standard I2C operations */
struct stm32_i2c_priv_s *priv; /* Common driver private data structure */
};
/************************************************************************************
* Private Function Prototypes
************************************************************************************/
@ -295,15 +287,15 @@ static inline void stm32_i2c_modifyreg(FAR struct stm32_i2c_priv_s *priv,
static inline void stm32_i2c_modifyreg32(FAR struct stm32_i2c_priv_s *priv,
uint8_t offset, uint32_t clearbits,
uint32_t setbits);
static inline void stm32_i2c_sem_wait(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv);
#ifdef CONFIG_STM32_I2C_DYNTIMEO
static useconds_t stm32_i2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs);
#endif /* CONFIG_STM32_I2C_DYNTIMEO */
static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_destroy(FAR struct i2c_master_s *dev);
static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv);
static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv);
#ifdef CONFIG_I2C_TRACE
static void stm32_i2c_tracereset(FAR struct stm32_i2c_priv_s *priv);
static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t status);
@ -331,8 +323,6 @@ static int stm32_i2c3_isr(int irq, void *context);
#endif
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_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count);
@ -340,6 +330,13 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
* Private Data
************************************************************************************/
/* Device Structures, Instantiation */
const struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
};
#ifdef CONFIG_STM32_I2C1
static const struct stm32_i2c_config_s stm32_i2c1_config =
{
@ -357,6 +354,7 @@ static const struct stm32_i2c_config_s stm32_i2c1_config =
struct stm32_i2c_priv_s stm32_i2c1_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c1_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -386,6 +384,7 @@ static const struct stm32_i2c_config_s stm32_i2c2_config =
struct stm32_i2c_priv_s stm32_i2c2_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c2_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -415,6 +414,7 @@ static const struct stm32_i2c_config_s stm32_i2c3_config =
struct stm32_i2c_priv_s stm32_i2c3_priv =
{
.ops = &stm32_i2c_ops,
.config = &stm32_i2c3_config,
.refs = 0,
.intstate = INTSTATE_IDLE,
@ -427,13 +427,6 @@ struct stm32_i2c_priv_s stm32_i2c3_priv =
};
#endif
/* Device Structures, Instantiation */
struct i2c_ops_s stm32_i2c_ops =
{
.transfer = stm32_i2c_transfer
};
/************************************************************************************
* Private Functions
************************************************************************************/
@ -532,9 +525,9 @@ static inline void stm32_i2c_modifyreg32(FAR struct stm32_i2c_priv_s *priv,
*
************************************************************************************/
static inline void stm32_i2c_sem_wait(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv)
{
while (sem_wait(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl) != 0)
while (sem_wait(&priv->sem_excl) != 0)
{
ASSERT(errno == EINTR);
}
@ -893,9 +886,9 @@ static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv)
*
************************************************************************************/
static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv)
{
sem_post(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_post(&priv->sem_excl);
}
/************************************************************************************
@ -906,11 +899,11 @@ static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev)
*
************************************************************************************/
static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv)
{
sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1);
sem_init(&priv->sem_excl, 0, 1);
#ifndef CONFIG_I2C_POLLED
sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0);
sem_init(&priv->sem_isr, 0, 0);
#endif
}
@ -922,11 +915,11 @@ static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev)
*
************************************************************************************/
static inline void stm32_i2c_sem_destroy(FAR struct i2c_master_s *dev)
static inline void stm32_i2c_sem_destroy(FAR struct stm32_i2c_priv_s *priv)
{
sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl);
sem_destroy(&priv->sem_excl);
#ifndef CONFIG_I2C_POLLED
sem_destroy(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr);
sem_destroy(&priv->sem_isr);
#endif
}
@ -1631,21 +1624,25 @@ static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv)
************************************************************************************/
/************************************************************************************
* Name: stm32_i2c_process
* Name: stm32_i2c_transfer
*
* Description:
* Common I2C transfer logic
* Generic I2C transfer function
*
************************************************************************************/
static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs, int count)
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
{
struct stm32_i2c_inst_s *inst = (struct stm32_i2c_inst_s *)dev;
FAR struct stm32_i2c_priv_s *priv = inst->priv;
uint32_t status = 0;
int errval = 0;
FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev;
uint32_t status = 0;
int ret = OK;
ASSERT(count);
DEBUGASSERT(dev != NULL && msgs != NULL && count > 0);
/* Ensure that address or flags don't change meanwhile */
stm32_i2c_sem_wait(priv);
/* Wait for any STOP in progress. */
@ -1700,7 +1697,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
if (stm32_i2c_sem_waitdone(priv) < 0)
{
status = stm32_i2c_getstatus(priv);
errval = ETIMEDOUT;
ret = -ETIMEDOUT;
i2cdbg("Timed out: CR1: %04x status: %08x\n",
stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET), status);
@ -1744,13 +1741,13 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* Bus Error */
errval = EIO;
ret = -EIO;
}
else if (status & I2C_INT_ARLO)
{
/* Arbitration Lost (master mode) */
errval = EAGAIN;
ret = -EAGAIN;
}
/* TODO Acknowledge failure */
@ -1759,19 +1756,19 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* Overrun/Underrun */
errval = EIO;
ret = -EIO;
}
else if (status & I2C_INT_PECERR)
{
/* PEC Error in reception */
errval = EPROTO;
ret = -EPROTO;
}
else if (status & I2C_INT_TIMEOUT)
{
/* Timeout or Tlow Error */
errval = ETIME;
ret = -ETIME;
}
/* This is not an error and should never happen since SMBus is not
@ -1784,7 +1781,7 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
* that want to trade their ability to master for a pin.
*/
errval = EINTR;
ret = -EINTR;
}
}
@ -1798,30 +1795,14 @@ static int stm32_i2c_process(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
{
/* I2C Bus is for some reason busy */
errval = EBUSY;
ret = -EBUSY;
}
/* Dump the trace result */
stm32_i2c_tracedump(priv);
stm32_i2c_sem_post(dev);
return -errval;
}
/************************************************************************************
* Name: stm32_i2c_transfer
*
* Description:
* Generic I2C transfer function
*
************************************************************************************/
static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s *msgs,
int count)
{
stm32_i2c_sem_wait(dev); /* ensure that address or flags don't change meanwhile */
return stm32_i2c_process(dev, msgs, count);
stm32_i2c_sem_post(priv);
return ret;
}
/************************************************************************************
@ -1839,7 +1820,6 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s
FAR struct i2c_master_s *up_i2cinitialize(int port)
{
struct stm32_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */
struct stm32_i2c_inst_s * inst = NULL; /* device, single instance */
int irqs;
#if STM32_PCLK1_FREQUENCY < 4000000
@ -1874,18 +1854,6 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
return NULL;
}
/* Allocate instance */
if (!(inst = kmm_malloc(sizeof(struct stm32_i2c_inst_s))))
{
return NULL;
}
/* Initialize instance */
inst->ops = &stm32_i2c_ops;
inst->priv = priv;
/* Init private data for the first time, increment refs count,
* power-up hardware and configure GPIOs.
*/
@ -1894,12 +1862,12 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
if ((volatile int)priv->refs++ == 0)
{
stm32_i2c_sem_init((struct i2c_master_s *)inst);
stm32_i2c_sem_init(priv);
stm32_i2c_init(priv);
}
irqrestore(irqs);
return (struct i2c_master_s *)inst;
return (struct i2c_master_s *)priv;
}
/************************************************************************************
@ -1912,23 +1880,23 @@ FAR struct i2c_master_s *up_i2cinitialize(int port)
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 (((struct stm32_i2c_inst_s *)dev)->priv->refs == 0)
if (priv->refs == 0)
{
return ERROR;
}
irqs = irqsave();
if (--((struct stm32_i2c_inst_s *)dev)->priv->refs)
if (--priv->refs)
{
irqrestore(irqs);
kmm_free(dev);
return OK;
}
@ -1936,13 +1904,11 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
/* Disable power and other HW resource (GPIO's) */
stm32_i2c_deinit(((struct stm32_i2c_inst_s *)dev)->priv);
stm32_i2c_deinit(priv);
/* Release unused resources */
stm32_i2c_sem_destroy((struct i2c_master_s *)dev);
kmm_free(dev);
stm32_i2c_sem_destroy(priv);
return OK;
}
@ -1957,7 +1923,6 @@ int up_i2cuninitialize(FAR struct i2c_master_s * dev)
#ifdef CONFIG_I2C_RESET
int up_i2creset(FAR struct i2c_master_s * dev)
{
struct stm32_i2c_priv_s * priv;
unsigned int clock_count;
unsigned int stretch_count;
uint32_t scl_gpio;
@ -1966,17 +1931,13 @@ int up_i2creset(FAR struct i2c_master_s * dev)
ASSERT(dev);
/* Get I2C private structure */
priv = ((struct stm32_i2c_inst_s *)dev)->priv;
/* Our caller must own a ref */
ASSERT(priv->refs > 0);
/* Lock out other clients */
stm32_i2c_sem_wait(dev);
stm32_i2c_sem_wait(priv);
/* De-init the port */
@ -2059,7 +2020,7 @@ out:
/* Release the port for re-use by other clients */
stm32_i2c_sem_post(dev);
stm32_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */

View File

@ -58,7 +58,6 @@
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/kmalloc.h>
#include <nuttx/clock.h>
#include <arch/board/board.h>
@ -214,38 +213,39 @@ struct tiva_i2c_config_s
struct tiva_i2c_priv_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
const struct tiva_i2c_config_s *config; /* Port configuration */
sem_t exclsem; /* Mutual exclusion semaphore */
sem_t exclsem; /* Mutual exclusion semaphore */
#ifndef CONFIG_I2C_POLLED
sem_t waitsem; /* Interrupt wait semaphore */
sem_t waitsem; /* Interrupt wait semaphore */
#endif
uint8_t refs; /* Reference count */
volatile uint8_t intstate; /* Interrupt handshake (see enum tiva_intstate_e) */
uint8_t refs; /* Reference count */
volatile uint8_t intstate; /* Interrupt handshake (see enum tiva_intstate_e) */
uint8_t msgc; /* Message count */
struct i2c_msg_s *msgv; /* Message list */
uint8_t *mptr; /* Current message buffer */
uint32_t frequency; /* Current I2C frequency */
int mcnt; /* Current message length */
uint16_t mflags; /* Current message flags */
uint32_t mstatus; /* MCS register at the end of the transfer */
uint8_t msgc; /* Message count */
struct i2c_msg_s *msgv; /* Message list */
uint8_t *mptr; /* Current message buffer */
uint32_t frequency; /* Current I2C frequency */
int mcnt; /* Current message length */
uint16_t mflags; /* Current message flags */
uint32_t mstatus; /* MCS register at the end of the transfer */
#ifdef CONFIG_TIVA_I2C_REGDEBUG
/* Register level debug */
bool wrlast; /* Last was a write */
uintptr_t addrlast; /* Last address */
uint32_t vallast; /* Last value */
int ntimes; /* Number of times */
bool wrlast; /* Last was a write */
uintptr_t addrlast; /* Last address */
uint32_t vallast; /* Last value */
int ntimes; /* Number of times */
#endif
#ifdef CONFIG_I2C_TRACE
/* I2C trace support */
int tndx; /* Trace array index */
int tcount; /* Number of events with this status */
systime_t ttime; /* Time when the trace was started */
uint32_t tstatus; /* Last status read */
int tndx; /* Trace array index */
int tcount; /* Number of events with this status */
systime_t ttime; /* Time when the trace was started */
uint32_t tstatus; /* Last status read */
/* The actual trace data */
@ -253,14 +253,6 @@ struct tiva_i2c_priv_s
#endif
};
/* I2C Device, Instance */
struct tiva_i2c_inst_s
{
const struct i2c_ops_s *ops; /* Standard I2C operations */
struct tiva_i2c_priv_s *priv; /* Common driver private data structure */
};
/************************************************************************************
* Private Function Prototypes
************************************************************************************/
@ -277,16 +269,16 @@ static inline uint32_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv,
static inline void tiva_i2c_putreg(struct tiva_i2c_priv_s *priv,
unsigned int offset, uint32_t value);
#endif
static inline void tiva_i2c_sem_wait(struct i2c_master_s *dev);
static inline void tiva_i2c_sem_wait(struct tiva_i2c_priv_s *priv);
#ifdef CONFIG_TIVA_I2C_DYNTIMEO
static useconds_t tiva_i2c_tousecs(int msgc, struct i2c_msg_s *msgv);
#endif /* CONFIG_TIVA_I2C_DYNTIMEO */
static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv);
static inline void tiva_i2c_sem_post(struct i2c_master_s *dev);
static inline void tiva_i2c_sem_init(struct i2c_master_s *dev);
static inline void tiva_i2c_sem_destroy(struct i2c_master_s *dev);
static inline void tiva_i2c_sem_post(struct tiva_i2c_priv_s *priv);
static inline void tiva_i2c_sem_init(struct tiva_i2c_priv_s *priv);
static inline void tiva_i2c_sem_destroy(struct tiva_i2c_priv_s *priv);
#ifdef CONFIG_I2C_TRACE
static void tiva_i2c_tracereset(struct tiva_i2c_priv_s *priv);
@ -336,8 +328,6 @@ static int tiva_i2c9_interrupt(int irq, void *context);
static int tiva_i2c_initialize(struct tiva_i2c_priv_s *priv, uint32_t frequency);
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_process(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
int msgc);
static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
int msgc);
@ -345,6 +335,13 @@ static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
* Private Data
************************************************************************************/
/* I2C Interface */
static const struct i2c_ops_s tiva_i2c_ops =
{
.transfer = tiva_i2c_transfer
};
#ifdef CONFIG_TIVA_I2C0
static const struct tiva_i2c_config_s tiva_i2c0_config =
{
@ -565,13 +562,6 @@ static const struct tiva_i2c_config_s tiva_i2c9_config =
static struct tiva_i2c_priv_s tiva_i2c9_priv;
#endif
/* Device Structures, Instantiation */
static const struct i2c_ops_s tiva_i2c_ops =
{
.transfer = tiva_i2c_transfer
};
/************************************************************************************
* Private Functions
************************************************************************************/
@ -696,11 +686,9 @@ static inline void tiva_i2c_putreg(struct tiva_i2c_priv_s *priv,
*
************************************************************************************/
static inline void tiva_i2c_sem_wait(struct i2c_master_s *dev)
static inline void tiva_i2c_sem_wait(struct tiva_i2c_priv_s *priv)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
while (sem_wait(&inst->priv->exclsem) != 0)
while (sem_wait(&priv->exclsem) != 0)
{
ASSERT(errno == EINTR);
}
@ -890,11 +878,9 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
*
************************************************************************************/
static inline void tiva_i2c_sem_post(struct i2c_master_s *dev)
static inline void tiva_i2c_sem_post(struct tiva_i2c_priv_s *priv)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
sem_post(&inst->priv->exclsem);
sem_post(&priv->exclsem);
}
/************************************************************************************
@ -905,13 +891,11 @@ static inline void tiva_i2c_sem_post(struct i2c_master_s *dev)
*
************************************************************************************/
static inline void tiva_i2c_sem_init(struct i2c_master_s *dev)
static inline void tiva_i2c_sem_init(struct tiva_i2c_priv_s *priv)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
sem_init(&inst->priv->exclsem, 0, 1);
sem_init(&priv->exclsem, 0, 1);
#ifndef CONFIG_I2C_POLLED
sem_init(&inst->priv->waitsem, 0, 0);
sem_init(&priv->waitsem, 0, 0);
#endif
}
@ -923,13 +907,11 @@ static inline void tiva_i2c_sem_init(struct i2c_master_s *dev)
*
************************************************************************************/
static inline void tiva_i2c_sem_destroy(struct i2c_master_s *dev)
static inline void tiva_i2c_sem_destroy(struct tiva_i2c_priv_s *priv)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
sem_destroy(&inst->priv->exclsem);
sem_destroy(&priv->exclsem);
#ifndef CONFIG_I2C_POLLED
sem_destroy(&inst->priv->waitsem);
sem_destroy(&priv->waitsem);
#endif
}
@ -1873,34 +1855,33 @@ static void tiva_i2c_setclock(struct tiva_i2c_priv_s *priv, uint32_t frequency)
}
/************************************************************************************
* Name: tiva_i2c_process
* Name: tiva_i2c_transfer
*
* Description:
* Common I2C transfer logic
* Generic I2C transfer function
*
************************************************************************************/
static int tiva_i2c_process(struct i2c_master_s *dev, struct i2c_msg_s *msgv, int msgc)
static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
int msgc)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
struct tiva_i2c_priv_s *priv = inst->priv;
struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev;
uint32_t regval;
int errcode = OK;
ASSERT(msgc > 0);
int ret = OK;
DEBUGASSERT(priv && priv->config && msgv && msgc > 0);
i2cvdbg("I2C%d: msgc=%d\n", priv->config->devno, msgc);
tiva_i2c_sem_wait(priv); /* Ensure that address or flags don't change meanwhile */
/* Reset mptr and mcnt to ensure an unexpected data interrupt doesn't
* overwrite stale data.
*/
priv->mcnt = 0;
priv->mptr = NULL;
priv->msgv = msgv;
priv->msgc = msgc;
priv->mcnt = 0;
priv->mptr = NULL;
priv->msgv = msgv;
priv->msgc = msgc;
priv->mstatus = 0;
/* Reset I2C trace logic */
@ -1930,7 +1911,7 @@ static int tiva_i2c_process(struct i2c_master_s *dev, struct i2c_msg_s *msgv, in
if (tiva_i2c_sem_waitdone(priv) < 0)
{
i2cdbg("I2C%d: ERROR: Timed out\n", priv->config->devno);
errcode = ETIMEDOUT;
ret = -ETIMEDOUT;
}
#if 0 /* I2CM_CS_CLKTO */
else if ((priv->mstatus & (I2CM_CS_ERROR | I2CM_CS_ARBLST | I2CM_CS_CLKTO)) != 0)
@ -1945,27 +1926,27 @@ static int tiva_i2c_process(struct i2c_master_s *dev, struct i2c_msg_s *msgv, in
{
/* Arbitration Lost */
errcode = EAGAIN;
ret = -EAGAIN;
}
else if ((priv->mstatus & (I2CM_CS_ADRACK | I2CM_CS_DATACK)) != 0)
{
/* Acknowledge Failure */
errcode = ENXIO;
ret = -ENXIO;
}
#if 0 /* I2CM_CS_CLKTO */
else if ((priv->mstatus & I2CM_CS_CLKTO) != 0)
{
/* Timeout */
errcode = ETIME;
ret = -ETIME;
}
#endif
else
{
/* Something else? */
errcode = EIO;
ret = -EIO;
}
}
@ -1994,11 +1975,11 @@ static int tiva_i2c_process(struct i2c_master_s *dev, struct i2c_msg_s *msgv, in
/* Is the busy condition a consequence of some other error? */
if (errcode == OK)
if (ret == OK)
{
/* No... then just being busy is the cause of the error */
errcode = EBUSY;
ret = -EBUSY;
}
}
@ -2010,31 +1991,8 @@ static int tiva_i2c_process(struct i2c_master_s *dev, struct i2c_msg_s *msgv, in
priv->mcnt = 0;
priv->mptr = NULL;
return -errcode;
}
/************************************************************************************
* Name: tiva_i2c_transfer
*
* Description:
* Generic I2C transfer function
*
************************************************************************************/
static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
int msgc)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
int ret;
DEBUGASSERT(inst && inst->priv && inst->priv->config);
i2cvdbg("I2C%d: msgc=%d\n", inst->priv->config->devno, msgc);
UNUSED(inst);
tiva_i2c_sem_wait(dev); /* Ensure that address or flags don't change meanwhile */
ret = tiva_i2c_process(dev, msgv, msgc);
tiva_i2c_sem_post(dev);
tiva_i2c_sem_post(priv);
return ret;
}
@ -2052,9 +2010,8 @@ static int tiva_i2c_transfer(struct i2c_master_s *dev, struct i2c_msg_s *msgv,
struct i2c_master_s *up_i2cinitialize(int port)
{
struct tiva_i2c_priv_s *priv = NULL; /* Private data of device with multiple instances */
struct tiva_i2c_inst_s *inst = NULL; /* Device, single instance */
const struct tiva_i2c_config_s *config; /* Constant configuration */
struct tiva_i2c_priv_s *priv = NULL;
const struct tiva_i2c_config_s *config;
int irqs;
i2cvdbg("I2C%d: Initialize\n", port);
@ -2138,19 +2095,9 @@ struct i2c_master_s *up_i2cinitialize(int port)
return NULL;
}
/* Allocate instance */
/* Initialize private device structure */
inst = kmm_malloc(sizeof(struct tiva_i2c_inst_s));
if (!inst)
{
i2cdbg("I2C%d: ERROR: Failed to allocate device instance\n", port);
return NULL;
}
/* Initialize instance */
inst->ops = &tiva_i2c_ops;
inst->priv = priv;
priv->ops = &tiva_i2c_ops;
/* Initialize private data for the first time, increment reference count,
* power-up hardware and configure GPIOs.
@ -2164,7 +2111,7 @@ struct i2c_master_s *up_i2cinitialize(int port)
/* Initialize the device structure */
priv->config = config;
tiva_i2c_sem_init((struct i2c_master_s *)inst);
tiva_i2c_sem_init(priv);
/* Initialize the I2C hardware */
@ -2172,7 +2119,7 @@ struct i2c_master_s *up_i2cinitialize(int port)
}
irqrestore(irqs);
return (struct i2c_master_s *)inst;
return (struct i2c_master_s *)priv;
}
/************************************************************************************
@ -2185,24 +2132,17 @@ struct i2c_master_s *up_i2cinitialize(int port)
int up_i2cuninitialize(struct i2c_master_s *dev)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
struct tiva_i2c_priv_s *priv ;
struct tiva_i2c_priv_s *priv = (struct tiva_i2c_priv_s *)dev;
int irqs;
DEBUGASSERT(inst && inst->priv);
priv = inst->priv;
DEBUGASSERT(priv && priv->config && priv->refs > 0);
DEBUGASSERT(priv->config && priv->refs > 0);
i2cvdbg("I2C%d: Uninitialize\n", priv->config->devno);
/* Decrement reference count and check for underflow */
irqs = irqsave();
/* Free this instance */
kmm_free(inst);
/* Check if the reference count will decrement to zero */
if (priv->refs < 2)
@ -2214,7 +2154,7 @@ int up_i2cuninitialize(struct i2c_master_s *dev)
/* Release unused resources */
tiva_i2c_sem_destroy(dev);
tiva_i2c_sem_destroy(priv);
}
else
{
@ -2238,20 +2178,15 @@ int up_i2cuninitialize(struct i2c_master_s *dev)
#ifdef CONFIG_I2C_RESET
int up_i2creset(struct i2c_master_s *dev)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
struct tiva_i2c_priv_s *priv;
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(inst && inst->priv && inst->priv->config);
i2cvdbg("I2C%d:\n", inst->priv->config->devno);
/* Get I2C private structure */
priv = inst->priv;
DEBUGASSERT(priv && priv->config);
i2cvdbg("I2C%d:\n", priv->config->devno);
/* Our caller must own a ref */
@ -2259,7 +2194,7 @@ int up_i2creset(struct i2c_master_s *dev)
/* Lock out other clients */
tiva_i2c_sem_wait(dev);
tiva_i2c_sem_wait(priv);
/* Un-initialize the port */
@ -2345,7 +2280,7 @@ out:
/* Release the port for re-use by other clients */
tiva_i2c_sem_post(dev);
tiva_i2c_sem_post(priv);
return ret;
}
#endif /* CONFIG_I2C_RESET */