diff options
-rw-r--r-- | apps/system/i2c/i2c_dev.c | 1 | ||||
-rw-r--r-- | apps/system/i2c/i2c_main.c | 31 | ||||
-rw-r--r-- | apps/system/i2c/i2ctool.h | 2 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/chip/stm32_i2c.h | 3 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_i2c.c | 43 |
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 |