summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-08-30 19:48:47 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-08-30 19:48:47 +0000
commit0fb1d700e376c74efab18ea5f70a88eabececde1 (patch)
tree496df0236d9a88fabc2f7c5e5a2e0d685e99598d
parent7b01904121be6cb88d28005a77da9c1815593925 (diff)
downloadnuttx-0fb1d700e376c74efab18ea5f70a88eabececde1.tar.gz
nuttx-0fb1d700e376c74efab18ea5f70a88eabececde1.tar.bz2
nuttx-0fb1d700e376c74efab18ea5f70a88eabececde1.zip
I2C tool no longer hangs on dev command
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3930 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/system/i2c/i2c_dev.c1
-rw-r--r--apps/system/i2c/i2c_main.c31
-rw-r--r--apps/system/i2c/i2ctool.h2
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_i2c.h3
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.c43
5 files changed, 62 insertions, 18 deletions
diff --git a/apps/system/i2c/i2c_dev.c b/apps/system/i2c/i2c_dev.c
index a8340f0d8..2d9946be0 100644
--- a/apps/system/i2c/i2c_dev.c
+++ b/apps/system/i2c/i2c_dev.c
@@ -227,6 +227,7 @@ int cmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
}
}
i2ctool_printf(i2ctool, "\n");
+ i2ctool_flush(i2ctool);
}
(void)up_i2cuninitialize(dev);
diff --git a/apps/system/i2c/i2c_main.c b/apps/system/i2c/i2c_main.c
index 768054671..85ad90365 100644
--- a/apps/system/i2c/i2c_main.c
+++ b/apps/system/i2c/i2c_main.c
@@ -297,13 +297,13 @@ int i2c_parse(FAR struct i2ctool_s *i2ctool, int argc, char *argv[])
* Name: i2c_setup
****************************************************************************/
-static inline int i2c_setup(void)
+static inline int i2c_setup(FAR struct i2ctool_s *i2ctool)
{
/* Initialize the output stream */
#ifdef CONFIG_I2CTOOL_OUTDEV
- g_i2ctool.ss_outfd = open(CONFIG_I2CTOOL_OUTDEV, O_WRONLY);
- if (g_i2ctool.ss_outfd < 0)
+ i2ctool->ss_outfd = open(CONFIG_I2CTOOL_OUTDEV, O_WRONLY);
+ if (i2ctool->ss_outfd < 0)
{
fprintf(stderr, g_i2ccmdfailed, "open", errno);
return ERROR;
@@ -311,8 +311,8 @@ static inline int i2c_setup(void)
/* Create a standard C stream on the console device */
- g_i2ctool.ss_outstream = fdopen(g_i2ctool.ss_outfd, "w");
- if (!g_i2ctool.ss_outstream)
+ i2ctool->ss_outstream = fdopen(i2ctool->ss_outfd, "w");
+ if (!i2ctool->ss_outstream)
{
fprintf(stderr, g_i2ccmdfailed, "fdopen", errno);
return ERROR;
@@ -330,12 +330,12 @@ static inline int i2c_setup(void)
*
****************************************************************************/
-static void i2c_teardown(void)
+static void i2c_teardown(FAR struct i2ctool_s *i2ctool)
{
fflush(OUTSTREAM(&g_i2ctool));
#ifdef CONFIG_I2CTOOL_OUTDEV
- fclose(g_i2ctool.ss_outstream);
+ fclose(i2ctool->ss_outstream);
#endif
}
@@ -386,10 +386,11 @@ int MAIN_NAME(int argc, char *argv[])
/* Parse process the command line */
- i2c_setup();
+ i2c_setup(&g_i2ctool);
(void)i2c_parse(&g_i2ctool, argc, argv);
- i2c_teardown();
+ i2ctool_flush(&g_i2ctool);
+ i2c_teardown(&g_i2ctool);
return OK;
}
@@ -435,3 +436,15 @@ ssize_t i2ctool_write(FAR struct i2ctool_s *i2ctool, FAR const void *buffer, siz
return ret;
}
+/****************************************************************************
+ * Name: i2ctool_flush
+ *
+ * Description:
+ * Flush buffered I/O to the currently selected stream.
+ *
+ ****************************************************************************/
+
+void i2ctool_flush(FAR struct i2ctool_s *i2ctool)
+{
+ fflush(OUTSTREAM(i2ctool));
+}
diff --git a/apps/system/i2c/i2ctool.h b/apps/system/i2c/i2ctool.h
index 962600f43..5abd731aa 100644
--- a/apps/system/i2c/i2ctool.h
+++ b/apps/system/i2c/i2ctool.h
@@ -179,12 +179,12 @@ extern const char g_i2cxfrerror[];
ssize_t i2ctool_write(FAR struct i2ctool_s *i2ctool, FAR const void *buffer, size_t nbytes);
int i2ctool_printf(FAR struct i2ctool_s *i2ctool, const char *fmt, ...);
+void i2ctool_flush(FAR struct i2ctool_s *i2ctool);
/* Command handlers */
int cmd_bus(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
int cmd_dev(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
-int cmd_dump(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
int cmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
index 00a24b355..8e40a3598 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_i2c.h
@@ -147,7 +147,8 @@
#define I2C_SR1_TIMEOUT (1 << 14) /* Bit 14: Timeout or Tlow Error */
#define I2C_SR1_SMBALERT (1 << 15) /* Bit 15: SMBus Alert */
-#define I2C_SR1_ERRORMASK (I2C_SR1_BERR|I2C_SR1_ARLO|I2C_SR1_AF|I2C_SR1_OVR|I2C_SR1_PECERR)
+#define I2C_SR1_ERRORMASK (I2C_SR1_BERR|I2C_SR1_ARLO|I2C_SR1_AF|I2C_SR1_OVR|\
+ I2C_SR1_PECERR|I2C_SR1_TIMEOUT|I2C_SR1_SMBALERT)
/* Status register 2 */
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c
index 78a957dbe..605719246 100644
--- a/nuttx/arch/arm/src/stm32/stm32_i2c.c
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c
@@ -91,6 +91,16 @@
#if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2)
/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* Configuration ********************************************************************/
+/* Interrupt wait timeout in milliseconds */
+
+#ifndef CONFIG_STM32_I2CTIMEOMS
+# define CONFIG_STM32_I2CTIMEOMS 50
+#endif
+
+/************************************************************************************
* Private Types
************************************************************************************/
@@ -183,10 +193,27 @@ void inline stm32_i2c_sem_wait(FAR struct i2c_dev_s *dev)
int inline stm32_i2c_sem_waitisr(FAR struct i2c_dev_s *dev)
{
- while( sem_wait( &((struct stm32_i2c_inst_s *)dev)->priv->sem_isr ) != 0 ) {
- ASSERT(errno == EINTR);
+ struct timespec abstime;
+ irqstate_t flags;
+ int ret;
+
+ flags = irqsave();
+ do
+ {
+ (void)clock_settime(CLOCK_REALTIME, &abstime);
+ abstime.tv_nsec += CONFIG_STM32_I2CTIMEOMS * 1000 * 1000;
+ if (abstime.tv_nsec > 1000 * 1000 * 1000)
+ {
+ abstime.tv_sec++;
+ abstime.tv_nsec -= 1000 * 1000 * 1000;
+ }
+
+ ret = sem_timedwait(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, &abstime);
}
- return OK;
+ while (ret != OK && errno == EINTR);
+
+ irqrestore(flags);
+ return ret;
}
void inline stm32_i2c_sem_post(FAR struct i2c_dev_s *dev)
@@ -270,7 +297,7 @@ static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv)
static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
{
uint32_t status = stm32_i2c_getstatus(priv);
-
+
#ifdef NON_ISR
static uint32_t isr_count = 0;
static uint32_t old_status = 0xFFFF;
@@ -285,7 +312,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
/* Was start bit sent */
if (status & I2C_SR1_SB) {
-
+
/* Get run-time data */
priv->ptr = priv->msgv->buffer;
@@ -315,7 +342,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
else if (status & I2C_SR1_ADD10) {
/* \todo Finish 10-bit mode addressing */
-
+
}
/* Was address sent, continue with ether sending or reading data */
@@ -341,7 +368,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
/* More bytes to read */
else if ( status & I2C_SR1_RXNE ) {
-
+
/* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */
#ifdef NON_ISR
@@ -376,6 +403,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv)
*/
if (priv->dcnt<=0 && (status & I2C_SR1_BTF)) {
+
#ifdef NON_ISR
printf("BTF\n");
#endif
@@ -641,6 +669,7 @@ int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *msgs, int
if (stm32_i2c_sem_waitisr(dev) == ERROR) {
status = stm32_i2c_getstatus(inst->priv);
+ status_errno = ETIMEDOUT;
}
else status = inst->priv->status & 0xFFFF; /* clear SR2 (BUSY flag) as we've done successfully */
#else