summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-20 13:55:31 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-20 13:55:31 +0000
commit0375e765b1f7686f25a0159cfd409fbe33708f31 (patch)
tree913f1c3633c0c4c7998f2576d13438bb9472043c
parent202f234c3343a159ec01df2a1d9d00235391142d (diff)
downloadpx4-nuttx-0375e765b1f7686f25a0159cfd409fbe33708f31.tar.gz
px4-nuttx-0375e765b1f7686f25a0159cfd409fbe33708f31.tar.bz2
px4-nuttx-0375e765b1f7686f25a0159cfd409fbe33708f31.zip
Oops.. the up_i2creset function mysteriously disappeared from stm32_i2c.c
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5167 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/arm/src/stm32/Kconfig4
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.c115
2 files changed, 117 insertions, 2 deletions
diff --git a/nuttx/arch/arm/src/stm32/Kconfig b/nuttx/arch/arm/src/stm32/Kconfig
index 8b0cea32e..a0f9a4892 100644
--- a/nuttx/arch/arm/src/stm32/Kconfig
+++ b/nuttx/arch/arm/src/stm32/Kconfig
@@ -1623,12 +1623,12 @@ config STM32_I2C_DYNTIMEO
config STM32_I2C_DYNTIMEO_USECPERBYTE
int "Timeout Microseconds per Byte"
- default 0
+ default 500
depends on STM32_I2C_DYNTIMEO
config STM32_I2C_DYNTIMEO_STARTSTOP
int "Timeout for Start/Stop (Milliseconds)"
- default 5000
+ default 1000
depends on STM32_I2C_DYNTIMEO
config STM32_I2CTIMEOSEC
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c
index 2d1c365cd..12a036f80 100644
--- a/nuttx/arch/arm/src/stm32/stm32_i2c.c
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c
@@ -1967,4 +1967,119 @@ int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
return OK;
}
+/************************************************************************************
+ * Name: up_i2creset
+ *
+ * Description:
+ * Reset an I2C bus
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_I2C_RESET
+int up_i2creset(FAR struct i2c_dev_s * dev)
+{
+ struct stm32_i2c_priv_s * priv;
+ unsigned int clock_count;
+ unsigned int stretch_count;
+ unit32_ scl_gpio;
+ unit32_ sda_gpio;
+ int ret = ERROR;
+ irqstate_t state;
+
+ 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);
+
+ /* De-init the port */
+
+ stm32_i2c_deinit(priv);
+
+ /* Use GPIO configuration to un-wedge the bus */
+
+ scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin);
+ sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin);
+
+ /* Clock the bus until any slaves currently driving it let it go. */
+
+ clock_count = 0;
+ while (!stm32_gpioread(sda_gpio))
+ {
+ /* Give up if we have tried too hard */
+
+ if (clock_count++ > 1000)
+ {
+ goto out;
+ }
+
+ /* Sniff to make sure that clock stretching has finished.
+ *
+ * If the bus never relaxes, the reset has failed.
+ */
+
+ stretch_count = 0;
+ while (!stm32_gpioread(scl_gpio))
+ {
+ /* Give up if we have tried too hard */
+
+ if (stretch_count++ > 1000)
+ {
+ goto out;
+ }
+
+ up_udelay(10);
+ }
+
+ /* Drive SCL low */
+
+ stm32_gpiowrite(scl_gpio, 0);
+ up_udelay(10);
+
+ /* Drive SCL high again */
+
+ stm32_gpiowrite(scl_gpio, 1);
+ up_udelay(10);
+ }
+
+ /* Generate a start followed by a stop to reset slave
+ * state machines.
+ */
+
+ stm32_gpiowrite(sda_gpio, 0);
+ up_udelay(10);
+ stm32_gpiowrite(scl_gpio, 0);
+ up_udelay(10);
+ stm32_gpiowrite(scl_gpio, 1);
+ up_udelay(10);
+ stm32_gpiowrite(sda_gpio, 1);
+ up_udelay(10);
+
+ /* Revert the GPIO configuration. */
+
+ stm32_unconfiggpio(sda_gpio);
+ stm32_unconfiggpio(scl_gpio);
+
+ /* Re-init the port */
+
+ stm32_i2c_init(priv);
+ ret = OK;
+
+out:
+
+ /* Release the port for re-use by other clients */
+
+ stm32_i2c_sem_post(dev);
+ return ret;
+}
+#endif /* CONFIG_I2C_RESET */
+
#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */