summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/tiva/tiva_i2c.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-12-10 08:47:34 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-12-10 08:47:34 -0600
commit0d55865d0d03053ce293eb7ea5fcc3fd675c5ded (patch)
tree9c73c45f7aadc3df97823e5f37c59973856c24e0 /nuttx/arch/arm/src/tiva/tiva_i2c.c
parentd19d6e46bd287e8466b21857075eb471a661d4d4 (diff)
downloadnuttx-0d55865d0d03053ce293eb7ea5fcc3fd675c5ded.tar.gz
nuttx-0d55865d0d03053ce293eb7ea5fcc3fd675c5ded.tar.bz2
nuttx-0d55865d0d03053ce293eb7ea5fcc3fd675c5ded.zip
Tiva i2C: Lots of compilation fixes
Diffstat (limited to 'nuttx/arch/arm/src/tiva/tiva_i2c.c')
-rw-r--r--nuttx/arch/arm/src/tiva/tiva_i2c.c477
1 files changed, 213 insertions, 264 deletions
diff --git a/nuttx/arch/arm/src/tiva/tiva_i2c.c b/nuttx/arch/arm/src/tiva/tiva_i2c.c
index e437e13ff..a7781ed32 100644
--- a/nuttx/arch/arm/src/tiva/tiva_i2c.c
+++ b/nuttx/arch/arm/src/tiva/tiva_i2c.c
@@ -63,14 +63,16 @@
#include "up_arch.h"
+#include "tiva_gpio.h"
+#include "chip/tiva_pinmap.h"
#include "chip/tiva_syscontrol.h"
#include "tiva_i2c.h"
/* At least one I2C peripheral must be enabled */
-#if defined(CONFIG_TIVA_I2C1) || defined(CONFIG_TIVA_I2C2) || \
- defined(CONFIG_TIVA_I2C3) || defined(CONFIG_TIVA_I2C4) || \
- defined(CONFIG_TIVA_I2C5)
+#if defined(CONFIG_TIVA_I2C0) || defined(CONFIG_TIVA_I2C1) || \
+ defined(CONFIG_TIVA_I2C2) || defined(CONFIG_TIVA_I2C3) || \
+ defined(CONFIG_TIVA_I2C4) || defined(CONFIG_TIVA_I2C5)
/************************************************************************************
* Pre-processor Definitions
@@ -104,9 +106,10 @@
/* Macros to convert a I2C pin to a GPIO output */
-#define I2C_OUTPUT (GPIO_OUTPUT | GPIO_FLOAT | GPIO_OPENDRAIN |\
- GPIO_SPEED_50MHz | GPIO_OUTPUT_SET)
+#define I2C_INPUT (GPIO_FUNC_INPUT)
+#define I2C_OUTPUT (GPIO_FUNC_ODOUTPUT | GPIO_PADTYPE_OD | GPIO_VALUE_ONE)
+#define MKI2C_INPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_INPUT)
#define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT)
/* Debug ****************************************************************************/
@@ -199,9 +202,9 @@ struct tiva_i2c_priv_s
{
const struct tiva_i2c_config_s *config; /* Port configuration */
int refs; /* Reference count */
- sem_t sem_excl; /* Mutual exclusion semaphore */
+ sem_t exclsem; /* Mutual exclusion semaphore */
#ifndef CONFIG_I2C_POLLED
- sem_t sem_isr; /* Interrupt wait semaphore */
+ sem_t waitsem; /* Interrupt wait semaphore */
#endif
volatile uint8_t intstate; /* Interrupt handshake (see enum tiva_intstate_e) */
@@ -221,8 +224,6 @@ struct tiva_i2c_priv_s
struct tiva_trace_s trace[CONFIG_I2C_NTRACE];
#endif
-
- uint32_t status; /* End of transfer SR2|SR1 status */
};
/* I2C Device, Instance */
@@ -246,8 +247,8 @@ 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);
static inline void tiva_i2c_modifyreg(struct tiva_i2c_priv_s *priv,
- uint8_t offset, uint16_t clearbits,
- uint16_t setbits);
+ uint8_t offset, uint16_t clearbits,
+ uint16_t setbits);
static inline void tiva_i2c_sem_wait(struct i2c_dev_s *dev);
#ifdef CONFIG_TIVA_I2C_DYNTIMEO
@@ -264,60 +265,59 @@ static inline void tiva_i2c_sem_destroy(struct i2c_dev_s *dev);
static void tiva_i2c_tracereset(struct tiva_i2c_priv_s *priv);
static void tiva_i2c_tracenew(struct tiva_i2c_priv_s *priv, uint32_t status);
static void tiva_i2c_traceevent(struct tiva_i2c_priv_s *priv,
- enum tiva_trace_e event, uint32_t parm);
+ enum tiva_trace_e event, uint32_t parm);
static void tiva_i2c_tracedump(struct tiva_i2c_priv_s *priv);
#endif /* CONFIG_I2C_TRACE */
-static void tiva_i2c_setclock(struct tiva_i2c_priv_s *priv,
- uint32_t frequency);
static inline void tiva_i2c_sendstart(struct tiva_i2c_priv_s *priv);
static inline void tiva_i2c_clrstart(struct tiva_i2c_priv_s *priv);
static inline void tiva_i2c_sendstop(struct tiva_i2c_priv_s *priv);
-static inline uint32_t tiva_i2c_getstatus(struct tiva_i2c_priv_s *priv);
-static int tiva_i2c_isr(struct tiva_i2c_priv_s * priv);
+static int tiva_i2c_interrupt(struct tiva_i2c_priv_s * priv, uint32_t status);
#ifndef CONFIG_I2C_POLLED
#ifdef CONFIG_TIVA_I2C0
-static int tiva_i2c0_isr(int irq, void *context);
+static int tiva_i2c0_interrupt(int irq, void *context);
#endif
#ifdef CONFIG_TIVA_I2C1
-static int tiva_i2c1_isr(int irq, void *context);
+static int tiva_i2c1_interrupt(int irq, void *context);
#endif
#ifdef CONFIG_TIVA_I2C2
-static int tiva_i2c2_isr(int irq, void *context);
+static int tiva_i2c2_interrupt(int irq, void *context);
#endif
#ifdef CONFIG_TIVA_I2C3
-static int tiva_i2c3_isr(int irq, void *context);
+static int tiva_i2c3_interrupt(int irq, void *context);
#endif
#ifdef CONFIG_TIVA_I2C4
-static int tiva_i2c4_isr(int irq, void *context);
+static int tiva_i2c4_interrupt(int irq, void *context);
#endif
#ifdef CONFIG_TIVA_I2C5
-static int tiva_i2c5_isr(int irq, void *context);
+static int tiva_i2c5_interrupt(int irq, void *context);
#endif
#endif /* !CONFIG_I2C_POLLED */
static int tiva_i2c_initialize(struct tiva_i2c_priv_s *priv);
static int tiva_i2c_uninitialize(struct tiva_i2c_priv_s *priv);
+static uint32_t tiva_i2c_setclock(struct tiva_i2c_priv_s *priv,
+ uint32_t frequency);
static uint32_t tiva_i2c_setfrequency(struct i2c_dev_s *dev,
- uint32_t frequency);
+ uint32_t frequency);
static int tiva_i2c_setaddress(struct i2c_dev_s *dev, int addr, int nbits);
static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
- int count);
+ int count);
static int tiva_i2c_write(struct i2c_dev_s *dev, const uint8_t *buffer,
- int buflen);
+ int buflen);
static int tiva_i2c_read(struct i2c_dev_s *dev, uint8_t *buffer, int buflen);
#ifdef CONFIG_I2C_WRITEREAD
static int tiva_i2c_writeread(struct i2c_dev_s *dev,
- const uint8_t *wbuffer, int wbuflen,
- uint8_t *buffer, int buflen);
+ const uint8_t *wbuffer, int wbuflen,
+ uint8_t *buffer, int buflen);
#endif /* CONFIG_I2C_WRITEREAD */
#ifdef CONFIG_I2C_TRANSFER
static int tiva_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
- int count);
+ int count);
#endif /* CONFIG_I2C_TRANSFER */
/************************************************************************************
@@ -334,24 +334,13 @@ static const struct tiva_i2c_config_s tiva_i2c0_config =
.scl_pin = GPIO_I2C0_SCL,
.sda_pin = GPIO_I2C0_SDA,
#ifndef CONFIG_I2C_POLLED
- .isr = tiva_i2c0_isr,
+ .isr = tiva_i2c0_interrupt,
.irq = TIVA_IRQ_I2C0,
#endif
.devno = 0,
};
-static struct tiva_i2c_priv_s tiva_i2c0_priv =
-{
- .config = &tiva_i2c0_config,
- .refs = 0,
- .intstate = INTSTATE_IDLE,
- .msgc = 0,
- .msgv = NULL,
- .ptr = NULL,
- .dcnt = 0,
- .flags = 0,
- .status = 0
-};
+static struct tiva_i2c_priv_s tiva_i2c0_priv;
#endif
#ifdef CONFIG_TIVA_I2C1
@@ -364,24 +353,13 @@ static const struct tiva_i2c_config_s tiva_i2c1_config =
.scl_pin = GPIO_I2C1_SCL,
.sda_pin = GPIO_I2C1_SDA,
#ifndef CONFIG_I2C_POLLED
- .isr = tiva_i2c1_isr,
+ .isr = tiva_i2c1_interrupt,
.irq = TIVA_IRQ_I2C1,
#endif
.devno = 1,
};
-static struct tiva_i2c_priv_s tiva_i2c1_priv =
-{
- .config = &tiva_i2c1_config,
- .refs = 0,
- .intstate = INTSTATE_IDLE,
- .msgc = 0,
- .msgv = NULL,
- .ptr = NULL,
- .dcnt = 0,
- .flags = 0,
- .status = 0
-};
+static struct tiva_i2c_priv_s tiva_i2c1_priv;
#endif
#ifdef CONFIG_TIVA_I2C2
@@ -394,24 +372,13 @@ static const struct tiva_i2c_config_s tiva_i2c2_config =
.scl_pin = GPIO_I2C2_SCL,
.sda_pin = GPIO_I2C2_SDA,
#ifndef CONFIG_I2C_POLLED
- .isr = tiva_i2c2_isr,
+ .isr = tiva_i2c2_interrupt,
.irq = TIVA_IRQ_I2C2,
#endif
.devno = 2,
};
-static struct tiva_i2c_priv_s tiva_i2c2_priv =
-{
- .config = &tiva_i2c2_config,
- .refs = 0,
- .intstate = INTSTATE_IDLE,
- .msgc = 0,
- .msgv = NULL,
- .ptr = NULL,
- .dcnt = 0,
- .flags = 0,
- .status = 0
-};
+static struct tiva_i2c_priv_s tiva_i2c2_priv;
#endif
#ifdef CONFIG_TIVA_I2C3
@@ -424,24 +391,13 @@ static const struct tiva_i2c_config_s tiva_i2c3_config =
.scl_pin = GPIO_I2C3_SCL,
.sda_pin = GPIO_I2C3_SDA,
#ifndef CONFIG_I2C_POLLED
- .isr = tiva_i2c3_isr,
+ .isr = tiva_i2c3_interrupt,
.irq = TIVA_IRQ_I2C3,
#endif
.devno = 3,
};
-static struct tiva_i2c_priv_s tiva_i2c3_priv =
-{
- .config = &tiva_i2c3_config,
- .refs = 0,
- .intstate = INTSTATE_IDLE,
- .msgc = 0,
- .msgv = NULL,
- .ptr = NULL,
- .dcnt = 0,
- .flags = 0,
- .status = 0
-};
+static struct tiva_i2c_priv_s tiva_i2c3_priv;
#endif
#ifdef CONFIG_TIVA_I2C4
@@ -454,24 +410,13 @@ static const struct tiva_i2c_config_s tiva_i2c4_config =
.scl_pin = GPIO_I2C4_SCL,
.sda_pin = GPIO_I2C4_SDA,
#ifndef CONFIG_I2C_POLLED
- .isr = tiva_i2c4_isr,
+ .isr = tiva_i2c4_interrupt,
.irq = TIVA_IRQ_I2C4,
#endif
.devno = 4,
};
-static struct tiva_i2c_priv_s tiva_i2c4_priv =
-{
- .config = &tiva_i2c4_config,
- .refs = 0,
- .intstate = INTSTATE_IDLE,
- .msgc = 0,
- .msgv = NULL,
- .ptr = NULL,
- .dcnt = 0,
- .flags = 0,
- .status = 0
-};
+static struct tiva_i2c_priv_s tiva_i2c4_priv;
#endif
#ifdef CONFIG_TIVA_I2C5
@@ -484,24 +429,13 @@ static const struct tiva_i2c_config_s tiva_i2c5_config =
.scl_pin = GPIO_I2C5_SCL,
.sda_pin = GPIO_I2C5_SDA,
#ifndef CONFIG_I2C_POLLED
- .isr = tiva_i2c5_isr,
+ .isr = tiva_i2c5_interrupt,
.irq = TIVA_IRQ_I2C5,
#endif
.devno = 5,
};
-static struct tiva_i2c_priv_s tiva_i2c5_priv =
-{
- .config = &tiva_i2c5_config,
- .refs = 0,
- .intstate = INTSTATE_IDLE,
- .msgc = 0,
- .msgv = NULL,
- .ptr = NULL,
- .dcnt = 0,
- .flags = 0,
- .status = 0
-};
+static struct tiva_i2c_priv_s tiva_i2c5_priv;
#endif
/* Device Structures, Instantiation */
@@ -536,7 +470,7 @@ static const struct i2c_ops_s tiva_i2c_ops =
*
************************************************************************************/
-static inline uint16_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv,
+static inline uint32_t tiva_i2c_getreg(struct tiva_i2c_priv_s *priv,
unsigned int offset)
{
return getreg32(priv->config->base + offset);
@@ -583,7 +517,7 @@ static inline void tiva_i2c_sem_wait(struct i2c_dev_s *dev)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
- while (sem_wait(&inst->priv->sem_excl) != 0)
+ while (sem_wait(&inst->priv->exclsem) != 0)
{
ASSERT(errno == EINTR);
}
@@ -636,8 +570,12 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
flags = irqsave();
- /* Enable I2C interrupts */
-#warning Missing logic
+ /* Enable the master interrupt. The I2C master module generates an interrupt when
+ * a transaction completes (either transmit or receive), when arbitration is lost,
+ * or when an error occurs during a transaction.
+ */
+
+ tiva_i2c_putreg(priv, TIVA_I2CM_IMR_OFFSET, I2CM_IMR_IM);
/* Signal the interrupt handler that we are waiting. NOTE: Interrupts
* are currently disabled but will be temporarily re-enabled below when
@@ -678,7 +616,7 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
/* Wait until either the transfer is complete or the timeout expires */
- ret = sem_timedwait(&priv->sem_isr, &abstime);
+ ret = sem_timedwait(&priv->waitsem, &abstime);
if (ret != OK && errno != EINTR)
{
/* Break out of the loop on irrecoverable errors. This would
@@ -699,7 +637,8 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
priv->intstate = INTSTATE_IDLE;
/* Disable I2C interrupts */
-#warning Missing logic
+
+ tiva_i2c_putreg(priv, TIVA_I2CM_IMR_OFFSET, 0);
irqrestore(flags);
return ret;
@@ -710,6 +649,7 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
uint32_t timeout;
uint32_t start;
uint32_t elapsed;
+ uint32_t status;
int ret;
/* Get the timeout value */
@@ -730,11 +670,15 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
do
{
- /* Poll by simply calling the timer interrupt handler until it
- * reports that it is done.
+ /* Read the raw interrupt status */
+
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_RIS_OFFSET);
+
+ /* Poll by simply calling the timer interrupt handler with the raw
+ * interrupt status until it reports that it is done.
*/
- tiva_i2c_isr(priv);
+ tiva_i2c_interrupt(priv, status);
/* Calculate the elapsed time */
@@ -746,7 +690,7 @@ static inline int tiva_i2c_sem_waitdone(struct tiva_i2c_priv_s *priv)
while (priv->intstate != INTSTATE_DONE && elapsed < timeout);
i2cvdbg("intstate: %d elapsed: %d threshold: %d status: %08x\n",
- priv->intstate, elapsed, timeout, priv->status);
+ priv->intstate, elapsed, timeout, status);
/* Set the interrupt state back to IDLE */
@@ -769,8 +713,6 @@ static inline void tiva_i2c_sem_waitstop(struct tiva_i2c_priv_s *priv)
uint32_t start;
uint32_t elapsed;
uint32_t timeout;
- uint32_t cr1;
- uint32_t sr1;
/* Select a timeout */
@@ -824,7 +766,7 @@ static inline void tiva_i2c_sem_post(struct i2c_dev_s *dev)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
- sem_post(&inst->priv->sem_excl);
+ sem_post(&inst->priv->exclsem);
}
/************************************************************************************
@@ -839,9 +781,9 @@ static inline void tiva_i2c_sem_init(struct i2c_dev_s *dev)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
- sem_init(&inst->priv->sem_excl, 0, 1);
+ sem_init(&inst->priv->exclsem, 0, 1);
#ifndef CONFIG_I2C_POLLED
- sem_init(&inst->priv->sem_isr, 0, 0);
+ sem_init(&inst->priv->waitsem, 0, 0);
#endif
}
@@ -857,9 +799,9 @@ static inline void tiva_i2c_sem_destroy(struct i2c_dev_s *dev)
{
struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
- sem_destroy(&inst->priv->sem_excl);
+ sem_destroy(&inst->priv->exclsem);
#ifndef CONFIG_I2C_POLLED
- sem_destroy(&inst->priv->sem_isr);
+ sem_destroy(&inst->priv->waitsem);
#endif
}
@@ -978,35 +920,6 @@ static void tiva_i2c_tracedump(struct tiva_i2c_priv_s *priv)
#endif /* CONFIG_I2C_TRACE */
/************************************************************************************
- * Name: tiva_i2c_setclock
- *
- * Description:
- * Set the I2C clock
- *
- ************************************************************************************/
-
-static void tiva_i2c_setclock(struct tiva_i2c_priv_s *priv, uint32_t frequency)
-{
- uint16_t cr1;
- uint16_t ccr;
- uint16_t trise;
- uint16_t freqmhz;
- uint16_t speed;
-
- /* Disable the selected I2C peripheral to configure TRISE */
-#warning Missing logic
-
- /* Update timing and control registers */
-#warning Missing logic
-
- /* Configure I2C frequency */
-#warning Missing logic
-
- /* Re-enable the peripheral (or not) */
-#warning Missing logic
-}
-
-/************************************************************************************
* Name: tiva_i2c_sendstart
*
* Description:
@@ -1047,30 +960,15 @@ static inline void tiva_i2c_sendstop(struct tiva_i2c_priv_s *priv)
}
/************************************************************************************
- * Name: tiva_i2c_getstatus
- *
- * Description:
- * Get 32-bit status (SR1 and SR2 combined)
- *
- ************************************************************************************/
-
-static inline uint32_t tiva_i2c_getstatus(struct tiva_i2c_priv_s *priv)
-{
-#warning Missing logic
-}
-
-/************************************************************************************
- * Name: tiva_i2c_isr
+ * Name: tiva_i2c_interrupt
*
* Description:
* Common Interrupt Service Routine
*
************************************************************************************/
-static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
+static int tiva_i2c_interrupt(struct tiva_i2c_priv_s *priv, uint32_t status)
{
- uint32_t status = tiva_i2c_getstatus(priv);
-
/* Check for new trace setup */
tiva_i2c_tracenew(priv, status);
@@ -1082,8 +980,8 @@ static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
tiva_i2c_traceevent(priv, I2CEVENT_SENDADDR, priv->msgc);
/* We check for msgc > 0 here as an unexpected interrupt with
- * I2C_SR1_SB set due to noise on the I2C cable can otherwise cause
- * msgc to wrap causing memory overwrite
+ * due to noise on the I2C cable can otherwise cause msgc to
+ * wrap causing memory overwrite
*/
if (priv->msgc > 0 && priv->msgv != NULL)
@@ -1114,14 +1012,6 @@ static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
}
}
- /* In 10-bit addressing mode, was first byte sent */
-
- else if ((status & I2C_SR1_ADD10) != 0)
- {
- /* TODO: Finish 10-bit mode addressing. */
-#warning Missing logic
- }
-
/* Was address sent, continue with either sending or reading data */
#warning Missing logic
@@ -1250,7 +1140,7 @@ static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
* and wake it up.
*/
- sem_post(&priv->sem_isr);
+ sem_post(&priv->waitsem);
priv->intstate = INTSTATE_DONE;
}
#else
@@ -1285,7 +1175,7 @@ static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
* and wake it up.
*/
- sem_post(&priv->sem_isr);
+ sem_post(&priv->waitsem);
priv->intstate = INTSTATE_DONE;
}
#else
@@ -1293,12 +1183,11 @@ static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
#endif
}
- priv->status = status;
return OK;
}
/************************************************************************************
- * Name: tiva_i2c0_isr
+ * Name: tiva_i2c0_interrupt
*
* Description:
* I2C0 interrupt service routine
@@ -1306,14 +1195,24 @@ static int tiva_i2c_isr(struct tiva_i2c_priv_s *priv)
************************************************************************************/
#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C0)
-static int tiva_i2c0_isr(int irq, void *context)
+static int tiva_i2c0_interrupt(int irq, void *context)
{
- return tiva_i2c_isr(&tiva_i2c0_priv);
+ struct tiva_i2c_priv_s *priv;
+ uint32_t status;
+
+ /* Read the masked interrupt status */
+
+ priv = &tiva_i2c0_priv;
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET);
+
+ /* Let the common interrupt handler do the rest of the work */
+
+ return tiva_i2c_interrupt(priv, status);
}
#endif
/************************************************************************************
- * Name: tiva_i2c1_isr
+ * Name: tiva_i2c1_interrupt
*
* Description:
* I2C1 interrupt service routine
@@ -1321,14 +1220,24 @@ static int tiva_i2c0_isr(int irq, void *context)
************************************************************************************/
#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C1)
-static int tiva_i2c1_isr(int irq, void *context)
+static int tiva_i2c1_interrupt(int irq, void *context)
{
- return tiva_i2c_isr(&tiva_i2c1_priv);
+ struct tiva_i2c_priv_s *priv;
+ uint32_t status;
+
+ /* Read the masked interrupt status */
+
+ priv = &tiva_i2c1_priv;
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET);
+
+ /* Let the common interrupt handler do the rest of the work */
+
+ return tiva_i2c_interrupt(priv, status);
}
#endif
/************************************************************************************
- * Name: tiva_i2c2_isr
+ * Name: tiva_i2c2_interrupt
*
* Description:
* I2C2 interrupt service routine
@@ -1336,14 +1245,24 @@ static int tiva_i2c1_isr(int irq, void *context)
************************************************************************************/
#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C2)
-static int tiva_i2c2_isr(int irq, void *context)
+static int tiva_i2c2_interrupt(int irq, void *context)
{
- return tiva_i2c_isr(&tiva_i2c2_priv);
+ struct tiva_i2c_priv_s *priv;
+ uint32_t status;
+
+ /* Read the masked interrupt status */
+
+ priv = &tiva_i2c2_priv;
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET);
+
+ /* Let the common interrupt handler do the rest of the work */
+
+ return tiva_i2c_interrupt(priv, status);
}
#endif
/************************************************************************************
- * Name: tiva_i2c3_isr
+ * Name: tiva_i2c3_interrupt
*
* Description:
* I2C2 interrupt service routine
@@ -1351,14 +1270,24 @@ static int tiva_i2c2_isr(int irq, void *context)
************************************************************************************/
#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C3)
-static int tiva_i2c3_isr(int irq, void *context)
+static int tiva_i2c3_interrupt(int irq, void *context)
{
- return tiva_i2c_isr(&tiva_i2c3_priv);
+ struct tiva_i2c_priv_s *priv;
+ uint32_t status;
+
+ /* Read the masked interrupt status */
+
+ priv = &tiva_i2c3_priv;
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET);
+
+ /* Let the common interrupt handler do the rest of the work */
+
+ return tiva_i2c_interrupt(priv, status);
}
#endif
/************************************************************************************
- * Name: tiva_i2c4_isr
+ * Name: tiva_i2c4_interrupt
*
* Description:
* I2C4 interrupt service routine
@@ -1366,14 +1295,24 @@ static int tiva_i2c3_isr(int irq, void *context)
************************************************************************************/
#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C4)
-static int tiva_i2c4_isr(int irq, void *context)
+static int tiva_i2c4_interrupt(int irq, void *context)
{
- return tiva_i2c_isr(&tiva_i2c4_priv);
+ struct tiva_i2c_priv_s *priv;
+ uint32_t status;
+
+ /* Read the masked interrupt status */
+
+ priv = &tiva_i2c4_priv;
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET);
+
+ /* Let the common interrupt handler do the rest of the work */
+
+ return tiva_i2c_interrupt(priv, status);
}
#endif
/************************************************************************************
- * Name: tiva_i2c5_isr
+ * Name: tiva_i2c5_interrupt
*
* Description:
* I2C5 interrupt service routine
@@ -1381,9 +1320,19 @@ static int tiva_i2c4_isr(int irq, void *context)
************************************************************************************/
#if !defined(CONFIG_I2C_POLLED) && defined(CONFIG_TIVA_I2C5)
-static int tiva_i2c5_isr(int irq, void *context)
+static int tiva_i2c5_interrupt(int irq, void *context)
{
- return tiva_i2c_isr(&tiva_i2c5_priv);
+ struct tiva_i2c_priv_s *priv;
+ uint32_t status;
+
+ /* Read the masked interrupt status */
+
+ priv = &tiva_i2c5_priv;
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_MIS_OFFSET);
+
+ /* Let the common interrupt handler do the rest of the work */
+
+ return tiva_i2c_interrupt(priv, status);
}
#endif
@@ -1403,23 +1352,23 @@ static int tiva_i2c_initialize(struct tiva_i2c_priv_s *priv)
/* Enable clocking to the I2C peripheral */
#ifdef TIVA_SYSCON_RCGCI2C
- up_modifyreg32(TIVA_SYSCON_RCGCI2C, 0, SYSCON_RCGCI2C(priv->devno));
+ modifyreg32(TIVA_SYSCON_RCGCI2C, 0, SYSCON_RCGCI2C(priv->config->devno));
#else
- up_modifyreg32(TIVA_SYSCON_RCGC1, 0, priv->rcgbit);
+ modifyreg32(TIVA_SYSCON_RCGC1, 0, priv->rcgbit);
#endif
/* Configure pins */
- ret = tiva_configgpio(priv->config->scl_pin)
+ ret = tiva_configgpio(priv->config->scl_pin);
if (ret < 0)
{
return ret;
}
- ret = tiva_configgpio(priv->config->sda_pin)
+ ret = tiva_configgpio(priv->config->sda_pin);
if (ret < 0)
{
- tiva_unconfiggpio(priv->config->scl_pin);
+ tiva_configgpio(MKI2C_INPUT(priv->config->scl_pin));
return ret;
}
@@ -1431,7 +1380,7 @@ static int tiva_i2c_initialize(struct tiva_i2c_priv_s *priv)
/* Configure the the initial I2C clock frequency. */
- tiva_i2c_setclock(priv, 100000);
+ (void)tiva_i2c_setclock(priv, 100000);
/* Attach interrupt handlers and enable interrupts at the NVIC (still
* disabled at the source).
@@ -1464,8 +1413,8 @@ static int tiva_i2c_uninitialize(struct tiva_i2c_priv_s *priv)
/* Unconfigure GPIO pins */
- tiva_unconfiggpio(priv->config->scl_pin);
- tiva_unconfiggpio(priv->config->sda_pin);
+ tiva_configgpio(MKI2C_INPUT(priv->config->scl_pin));
+ tiva_configgpio(MKI2C_INPUT(priv->config->sda_pin));
/* Disable and detach interrupts */
@@ -1477,40 +1426,27 @@ static int tiva_i2c_uninitialize(struct tiva_i2c_priv_s *priv)
/* Disable clocking */
#ifdef TIVA_SYSCON_RCGCI2C
- up_modifyreg32(TIVA_SYSCON_RCGCI2C, SYSCON_RCGCI2C(priv->devno), 0);
+ modifyreg32(TIVA_SYSCON_RCGCI2C, SYSCON_RCGCI2C(priv->config->devno), 0);
#else
- up_modifyreg32(TIVA_SYSCON_RCGC1, priv->rcgbit, 0);
+ modifyreg32(TIVA_SYSCON_RCGC1, priv->rcgbit, 0);
#endif
return OK;
}
/************************************************************************************
- * Device Driver Operations
- ************************************************************************************/
-
-/************************************************************************************
- * Name: tiva_i2c_setfrequency
+ * Name: tiva_i2c_setclock
*
* Description:
* Set the I2C frequency
*
************************************************************************************/
-static uint32_t tiva_i2c_setfrequency(struct i2c_dev_s *dev, uint32_t frequency)
+static uint32_t tiva_i2c_setclock(struct tiva_i2c_priv_s *priv, uint32_t frequency)
{
- struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
- struct tiva_i2c_priv_s *priv;
uint32_t regval;
uint32_t tmp;
- DEBUGASSERT(inst && inst->priv);
- priv = inst->priv;
-
- /* Get exclusive access to the I2C device */
-
- tiva_i2c_sem_wait(dev);
-
/* Calculate the clock divider that results in the highest frequency that
* is than or equal to the desired speed.
*/
@@ -1536,9 +1472,31 @@ static uint32_t tiva_i2c_setfrequency(struct i2c_dev_s *dev, uint32_t frequency)
}
#endif
- /* Remember the frequency setting */
+ return frequency;
+}
+/************************************************************************************
+ * Name: tiva_i2c_setfrequency
+ *
+ * Description:
+ * Set the I2C frequency
+ *
+ ************************************************************************************/
+
+static uint32_t tiva_i2c_setfrequency(struct i2c_dev_s *dev, uint32_t frequency)
+{
+ struct tiva_i2c_inst_s *inst = (struct tiva_i2c_inst_s *)dev;
+ struct tiva_i2c_priv_s *priv;
- intst->frequency = frequency;
+ DEBUGASSERT(inst && inst->priv);
+ priv = inst->priv;
+
+ /* Get exclusive access to the I2C device */
+
+ tiva_i2c_sem_wait(dev);
+
+ /* Set the clocking for the selected frequency */
+
+ inst->frequency = tiva_i2c_setclock(priv, frequency);
tiva_i2c_sem_post(dev);
return frequency;
@@ -1617,7 +1575,7 @@ static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
tiva_i2c_tracereset(priv);
- /* Set I2C clock frequency (on change it toggles I2C_CR1_PE !) */
+ /* Set I2C clock frequency */
tiva_i2c_setclock(priv, inst->frequency);
@@ -1625,7 +1583,6 @@ static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
* interrupts will be enabled within tiva_i2c_waitdone().
*/
- priv->status = 0;
tiva_i2c_sendstart(priv);
/* Wait for an ISR, if there was a timeout, fetch latest status to get
@@ -1634,7 +1591,9 @@ static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
if (tiva_i2c_sem_waitdone(priv) < 0)
{
- status = tiva_i2c_getstatus(priv);
+ /* Read the raw interrupt status */
+
+ status = tiva_i2c_getreg(priv, TIVA_I2CM_RIS_OFFSET);
errval = ETIMEDOUT;
i2cdbg("Timed out: status: 0x%08x\n", status);
@@ -1646,55 +1605,36 @@ static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
*/
tiva_i2c_clrstart(priv);
-
- /* Clear busy flag in case of timeout */
-
- status = priv->status & 0xffff;
- }
- else
- {
- /* clear SR2 (BUSY flag) as we've done successfully */
-
- status = priv->status & 0xffff;
}
/* Check for error status conditions */
-
- if ((status & I2C_SR1_ERRORMASK) != 0)
+#warning Missing logic
{
- /* I2C_SR1_ERRORMASK is the 'OR' of the following individual bits: */
-
- if (status & I2C_SR1_BERR)
{
/* Bus Error */
errval = EIO;
}
- else if (status & I2C_SR1_ARLO)
{
/* Arbitration Lost (master mode) */
errval = EAGAIN;
}
- else if (status & I2C_SR1_AF)
{
/* Acknowledge Failure */
errval = ENXIO;
}
- else if (status & I2C_SR1_OVR)
{
/* Overrun/Underrun */
errval = EIO;
}
- else if (status & I2C_SR1_PECERR)
{
/* PEC Error in reception */
errval = EPROTO;
}
- else if (status & I2C_SR1_TIMEOUT)
{
/* Timeout or Tlow Error */
@@ -1703,7 +1643,6 @@ static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
/* This is not an error and should never happen since SMBus is not enabled */
- else /* if (status & I2C_SR1_SMBALERT) */
{
/* SMBus alert is an optional signal with an interrupt line for devices
* that want to trade their ability to master for a pin.
@@ -1718,8 +1657,7 @@ static int tiva_i2c_process(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
* NOTE: We will only see this busy indication if tiva_i2c_sem_waitdone()
* fails above; Otherwise it is cleared.
*/
-
- else if ((status & (I2C_SR2_BUSY << 16)) != 0)
+#warning Missing logic
{
/* I2C Bus is for some reason busy */
@@ -1857,8 +1795,9 @@ static int tiva_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgs,
struct i2c_dev_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 */
+ 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 */
int irqs;
/* Get I2C private structure */
@@ -1867,32 +1806,38 @@ struct i2c_dev_s *up_i2cinitialize(int port)
{
#ifdef CONFIG_TIVA_I2C0
case 0:
- priv = (struct tiva_i2c_priv_s *)&tiva_i2c0_priv;
+ priv = &tiva_i2c0_priv;
+ config = &tiva_i2c0_config;
break;
#endif
#ifdef CONFIG_TIVA_I2C1
case 1:
- priv = (struct tiva_i2c_priv_s *)&tiva_i2c1_priv;
+ priv = &tiva_i2c1_priv;
+ config = &tiva_i2c1_config;
break;
#endif
#ifdef CONFIG_TIVA_I2C2
case 2:
- priv = (struct tiva_i2c_priv_s *)&tiva_i2c2_priv;
+ priv = &tiva_i2c2_priv;
+ config = &tiva_i2c2_config;
break;
#endif
#ifdef CONFIG_TIVA_I2C3
case 3:
- priv = (struct tiva_i2c_priv_s *)&tiva_i2c3_priv;
+ priv = &tiva_i2c3_priv;
+ config = &tiva_i2c3_config;
break;
#endif
#ifdef CONFIG_TIVA_I2C4
case 4:
- priv = (struct tiva_i2c_priv_s *)&tiva_i2c4_priv;
+ priv = &tiva_i2c4_priv;
+ config = &tiva_i2c4_config;
break;
#endif
#ifdef CONFIG_TIVA_I2C5
case 5:
- priv = (struct tiva_i2c_priv_s *)&tiva_i2c5_priv;
+ priv = &tiva_i2c5_priv;
+ config = &tiva_i2c5_config;
break;
#endif
default:
@@ -1906,6 +1851,10 @@ struct i2c_dev_s *up_i2cinitialize(int port)
return NULL;
}
+ /* Make sure that the device structure is inialized */
+
+ priv->config = config;
+
/* Initialize instance */
inst->ops = &tiva_i2c_ops;
@@ -2080,8 +2029,8 @@ int up_i2creset(struct i2c_dev_s *dev)
/* Revert the GPIO configuration. */
- tiva_unconfiggpio(sda_gpio);
- tiva_unconfiggpio(scl_gpio);
+ tiva_configgpio(MKI2C_INPUT(sda_gpio));
+ tiva_configgpio(MKI2C_INPUT(scl_gpio));
/* Re-init the port */
@@ -2097,4 +2046,4 @@ out:
}
#endif /* CONFIG_I2C_RESET */
-#endif /* CONFIG_TIVA_I2C1 ... CONFIG_TIVA_I2C5 */
+#endif /* CONFIG_TIVA_I2C0 ... CONFIG_TIVA_I2C5 */