aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2012-08-22 22:24:22 -0700
committerpx4dev <px4@purgatory.org>2012-08-22 22:24:22 -0700
commita3b78163c3bbcc64a7aa5ada6a0f62670b7fd1cc (patch)
tree60d23afdd5cd035daa620dcd88bcad6f3d6586ca
parent6669c7faa98fee1b32654706bc393009b048b930 (diff)
downloadpx4-firmware-a3b78163c3bbcc64a7aa5ada6a0f62670b7fd1cc.tar.gz
px4-firmware-a3b78163c3bbcc64a7aa5ada6a0f62670b7fd1cc.tar.bz2
px4-firmware-a3b78163c3bbcc64a7aa5ada6a0f62670b7fd1cc.zip
Add locking to the I2C bus reset API to prevent pre-emption and conflict when resetting at the same time that another transaction attempts to use the bus.
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_i2c.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c
index 2d4381577..cca7a24aa 100644
--- a/nuttx/arch/arm/src/stm32/stm32_i2c.c
+++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c
@@ -1946,17 +1946,26 @@ int up_i2cuninitialize(FAR struct i2c_dev_s * dev)
int up_i2creset(FAR struct i2c_dev_s * dev)
{
+ struct stm32_i2c_priv_s * priv;
unsigned clock_count;
unsigned stretch_count;
+ int ret = ERROR;
+ irqstate_t state;
- // ASSERT(dev);
-
- struct stm32_i2c_priv_s * priv = NULL;
+ 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);
@@ -1980,7 +1989,7 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
if (clock_count++ > 1000)
{
- return ERROR;
+ goto out;
}
/*
@@ -1997,7 +2006,7 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
if (stretch_count++ > 1000)
{
- return ERROR;
+ goto out;
}
up_udelay(10);
@@ -2041,8 +2050,15 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
/* Re-init the port */
stm32_i2c_init(priv);
+ ret = OK;
- return OK;
+out:
+
+ /* release the port for re-use by other clients */
+
+ stm32_i2c_sem_post(dev);
+
+ return ret;
}
#endif /* defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) */