diff options
author | px4dev <px4@purgatory.org> | 2012-08-22 22:24:22 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2012-08-22 22:24:22 -0700 |
commit | a3b78163c3bbcc64a7aa5ada6a0f62670b7fd1cc (patch) | |
tree | 60d23afdd5cd035daa620dcd88bcad6f3d6586ca /nuttx/arch/arm/src/stm32/stm32_i2c.c | |
parent | 6669c7faa98fee1b32654706bc393009b048b930 (diff) | |
download | px4-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.
Diffstat (limited to 'nuttx/arch/arm/src/stm32/stm32_i2c.c')
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_i2c.c | 28 |
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) */ |