mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
Merge pull request #2323 from thomaseichinger/i2c_mutex
periph/i2c: added means to make I2C thread-safe
This commit is contained in:
commit
ebadbd6da3
@ -12,6 +12,7 @@
|
||||
* @file
|
||||
* @brief Low-level I2C driver implementation
|
||||
* @author Baptiste Clenet <baptiste.clenet@xsoen.com>
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -19,7 +20,7 @@
|
||||
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "mutex.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/i2c.h"
|
||||
#include "instance/instance_sercom3.h"
|
||||
@ -41,6 +42,23 @@ static inline void _write(SercomI2cm *dev, char *data, int length);
|
||||
static inline void _read(SercomI2cm *dev, char *data, int length);
|
||||
static inline void _stop(SercomI2cm *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)
|
||||
{
|
||||
@ -191,6 +209,24 @@ int i2c_init_slave(i2c_t dev, uint8_t address)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -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>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@ -26,6 +27,7 @@
|
||||
|
||||
#include "cpu.h"
|
||||
#include "irq.h"
|
||||
#include "mutex.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/i2c.h"
|
||||
|
||||
@ -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;
|
||||
@ -105,6 +125,7 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed)
|
||||
/* enable device */
|
||||
_i2c_init(i2c, ccr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
*
|
||||
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @auhtor Thomas Eichinge <thomas.eichinger@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@ -25,6 +26,7 @@
|
||||
|
||||
#include "cpu.h"
|
||||
#include "irq.h"
|
||||
#include "mutex.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/i2c.h"
|
||||
|
||||
@ -43,6 +45,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;
|
||||
@ -201,6 +221,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);
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/i2c.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
@ -45,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;
|
||||
@ -200,6 +219,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);
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user