Skip to content

Commit

Permalink
periph/i2c: added means to make I2C thread-safe
Browse files Browse the repository at this point in the history
As discussed in #2289 this changes provide means to
use the i2c interface safely within multible threads.
  • Loading branch information
thomaseichinger committed Jan 19, 2015
1 parent c3cdfe7 commit 98f3150
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
39 changes: 39 additions & 0 deletions cpu/stm32f1/periph/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* For implementation details please refer to STM application note AN2824.
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* @}
*/
Expand All @@ -26,6 +27,7 @@

#include "cpu.h"
#include "irq.h"
#include "mutex.h"
#include "periph_conf.h"
#include "periph/i2c.h"

Expand All @@ -44,6 +46,24 @@ static inline void _clear_addr(I2C_TypeDef *dev);
static inline void _write(I2C_TypeDef *dev, char *data, int length);
static inline void _stop(I2C_TypeDef *dev);

/**
* @brief Array holding one pre-initialized mutex for each I2C device
*/
static mutex_t locks[] = {
#if I2C_0_EN
[I2C_0] = MUTEX_INIT,
#endif
#if I2C_1_EN
[I2C_1] = MUTEX_INIT,
#endif
#if I2C_2_EN
[I2C_2] = MUTEX_INIT
#endif
#if I2C_3_EN
[I2C_3] = MUTEX_INIT
#endif
};

int i2c_init_master(i2c_t dev, i2c_speed_t speed)
{
I2C_TypeDef *i2c;
Expand Down Expand Up @@ -105,6 +125,7 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed)
/* enable device */
_i2c_init(i2c, ccr);
}

return 0;
}

Expand Down Expand Up @@ -173,6 +194,24 @@ int i2c_init_slave(i2c_t dev, uint8_t address)
return -1;
}

int i2c_acquire(i2c_t dev)
{
if (dev >= I2C_NUMOF) {
return -1;
}
mutex_lock(&locks[dev]);
return 0;
}

int i2c_release(i2c_t dev)
{
if (dev >= I2C_NUMOF) {
return -1;
}
mutex_unlock(&locks[dev]);
return 0;
}

int i2c_read_byte(i2c_t dev, uint8_t address, char *data)
{
return i2c_read_bytes(dev, address, data, 1);
Expand Down
23 changes: 23 additions & 0 deletions drivers/include/periph/i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
7-bit addressing mode.
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*/

#ifndef __I2C_H
Expand Down Expand Up @@ -119,6 +120,28 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed);
*/
int i2c_init_slave(i2c_t dev, uint8_t address);

/**
* @brief Get mutually exclusive access to the given I2C bus
*
* In case the I2C device is busy, this function will block until the bus is free again.
*
* @param[in] dev I2C device to access
*
* @return 0 on success
* @return -1 on error
*/
int i2c_acquire(i2c_t dev);

/**
* @brief Release the given I2C device to be used by others
*
* @param[in] dev I2C device to release
*
* @return 0 on success
* @return -1 on error
*/
int i2c_release(i2c_t dev);

/**
* @brief Read one byte from an I2C device with the given address
*
Expand Down

0 comments on commit 98f3150

Please sign in to comment.