From b393cdad8de5e17d2422f7bd18206a72f0936384 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Mon, 28 Dec 2020 18:06:44 +0100 Subject: [PATCH] Added locking mechanism to MK22FN512xx I2C0 driver to allow for multithread use --- platform/mcu/MK22FN512xxx12/drivers/I2C0.c | 30 ++++++++++++++++++++++ platform/mcu/MK22FN512xxx12/drivers/I2C0.h | 20 +++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/platform/mcu/MK22FN512xxx12/drivers/I2C0.c b/platform/mcu/MK22FN512xxx12/drivers/I2C0.c index 214eb867..181cbe50 100644 --- a/platform/mcu/MK22FN512xxx12/drivers/I2C0.c +++ b/platform/mcu/MK22FN512xxx12/drivers/I2C0.c @@ -19,8 +19,12 @@ ***************************************************************************/ #include "I2C0.h" +#include #include +OS_MUTEX i2c_mutex; +OS_ERR err; + void i2c0_init() { SIM->SCGC4 |= SIM_SCGC4_I2C0(1); @@ -28,6 +32,8 @@ void i2c0_init() I2C0->A1 = 0; /* Module address when in slave mode */ I2C0->F = 0x2C; /* Divide bus clock by 576 */ I2C0->C1 |= I2C_C1_IICEN(1); /* Enable I2C module */ + + OSMutexCreate(&i2c_mutex, "", &err); } void i2c0_terminate() @@ -36,6 +42,8 @@ void i2c0_terminate() I2C0->C1 &= ~I2C_C1_IICEN(1); SIM->SCGC4 &= ~SIM_SCGC4_I2C0(1); + + OSMutexDel(&i2c_mutex, OS_OPT_DEL_NO_PEND, &err); } void i2c0_write(uint8_t addr, void* buf, size_t len, bool sendStop) @@ -110,3 +118,25 @@ bool i2c0_busy() { return (I2C0->S & I2C_S_BUSY_MASK); } + +bool i2c0_lockDevice() +{ + OSMutexPend(&i2c_mutex, 0, OS_OPT_PEND_NON_BLOCKING, NULL, &err); + + if(err == OS_ERR_NONE) + { + return true; + } + + return false; +} + +void i2c0_lockDeviceBlocking() +{ + OSMutexPend(&i2c_mutex, 0, OS_OPT_PEND_BLOCKING, NULL, &err); +} + +void i2c0_releaseDevice() +{ + OSMutexPost(&i2c_mutex, OS_OPT_POST_NONE, &err); +} diff --git a/platform/mcu/MK22FN512xxx12/drivers/I2C0.h b/platform/mcu/MK22FN512xxx12/drivers/I2C0.h index 48ef5db6..9ba4947f 100644 --- a/platform/mcu/MK22FN512xxx12/drivers/I2C0.h +++ b/platform/mcu/MK22FN512xxx12/drivers/I2C0.h @@ -62,4 +62,24 @@ void i2c0_read(uint8_t addr, void *buf, size_t len); */ bool i2c0_busy(); +/** + * Acquire exclusive ownership on the I2C peripheral by locking an internal + * mutex. This function is nonblocking and returs true if mutex has been + * successfully locked by the caller. + * @return true if device has been locked. + */ +bool i2c0_lockDevice(); + +/** + * Acquire exclusive ownership on the I2C peripheral by locking an internal + * mutex. In case mutex is already locked, this function blocks the execution + * flow until it becomes free again. + */ +void i2c0_lockDeviceBlocking(); + +/** + * Release exclusive ownership on the I2C peripheral. + */ +void i2c0_releaseDevice(); + #endif /* I2C0_H */