Guard RCC registers access with critical section (#854)
* Core: critical section macros. FuriHal: guard rcc registers access with critical section, fix condition race. * FuriHal: update documentation. Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
@@ -19,9 +19,11 @@ osMutexId_t furi_hal_i2c_bus_power_mutex = NULL;
|
||||
static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
||||
if (event == FuriHalI2cBusEventInit) {
|
||||
furi_hal_i2c_bus_power_mutex = osMutexNew(NULL);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if (event == FuriHalI2cBusEventDeinit) {
|
||||
osMutexDelete(furi_hal_i2c_bus_power_mutex);
|
||||
@@ -30,9 +32,13 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent
|
||||
} else if (event == FuriHalI2cBusEventUnlock) {
|
||||
furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK);
|
||||
} else if (event == FuriHalI2cBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if (event == FuriHalI2cBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,11 +51,15 @@ osMutexId_t furi_hal_i2c_bus_external_mutex = NULL;
|
||||
|
||||
static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
||||
if (event == FuriHalI2cBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if (event == FuriHalI2cBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,13 +86,12 @@ void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2c
|
||||
I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100;
|
||||
}
|
||||
LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct);
|
||||
|
||||
// I2C is enabled at this point
|
||||
LL_I2C_EnableAutoEndMode(handle->bus->i2c);
|
||||
LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK);
|
||||
LL_I2C_DisableOwnAddress2(handle->bus->i2c);
|
||||
LL_I2C_DisableGeneralCall(handle->bus->i2c);
|
||||
LL_I2C_EnableClockStretching(handle->bus->i2c);
|
||||
LL_I2C_Enable(handle->bus->i2c);
|
||||
} else if (event == FuriHalI2cBusHandleEventDeactivate) {
|
||||
LL_I2C_Disable(handle->bus->i2c);
|
||||
hal_gpio_write(&gpio_i2c_power_sda, 1);
|
||||
@@ -111,13 +120,12 @@ void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHal
|
||||
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
|
||||
I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100;
|
||||
LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct);
|
||||
|
||||
// I2C is enabled at this point
|
||||
LL_I2C_EnableAutoEndMode(handle->bus->i2c);
|
||||
LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK);
|
||||
LL_I2C_DisableOwnAddress2(handle->bus->i2c);
|
||||
LL_I2C_DisableGeneralCall(handle->bus->i2c);
|
||||
LL_I2C_EnableClockStretching(handle->bus->i2c);
|
||||
LL_I2C_Enable(handle->bus->i2c);
|
||||
} else if (event == FuriHalI2cBusHandleEventDeactivate) {
|
||||
LL_I2C_Disable(handle->bus->i2c);
|
||||
hal_gpio_write(&gpio_ext_pc0, 1);
|
||||
|
Reference in New Issue
Block a user