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:
parent
c9a7d48cb2
commit
30624c8dfa
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user