From 33892ebfb790c46e7f63aa6dd33e83e9159b8946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Fri, 21 Oct 2022 02:14:46 +0900 Subject: [PATCH] [FL-2818] FuriHal: add FuriHalCortexTimer, use it for i2c bus timeouts (#1900) * FuriHal: add FuriHalCortexTimer, use it for i2c bus timeouts * Furi: cleanup FuriHalCortexTimer sources and headers --- firmware/targets/f7/api_symbols.csv | 5 +++- .../targets/f7/furi_hal/furi_hal_cortex.c | 21 ++++++++++++-- firmware/targets/f7/furi_hal/furi_hal_i2c.c | 29 ++++++++++--------- .../furi_hal_include/furi_hal_cortex.h | 29 +++++++++++++++++++ 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 6aa8591e7..89f447157 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,3.4,, +Version,+,3.5,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -985,6 +985,9 @@ Function,+,furi_hal_console_tx_with_new_line,void,"const uint8_t*, size_t" Function,+,furi_hal_cortex_delay_us,void,uint32_t Function,-,furi_hal_cortex_init_early,void, Function,+,furi_hal_cortex_instructions_per_microsecond,uint32_t, +Function,+,furi_hal_cortex_timer_get,FuriHalCortexTimer,uint32_t +Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer +Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t" Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t" Function,-,furi_hal_crypto_init,void, diff --git a/firmware/targets/f7/furi_hal/furi_hal_cortex.c b/firmware/targets/f7/furi_hal/furi_hal_cortex.c index c9c8400a7..c2abd1b85 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_cortex.c +++ b/firmware/targets/f7/furi_hal/furi_hal_cortex.c @@ -2,6 +2,8 @@ #include +#define FURI_HAL_CORTEX_INSTRUCTIONS_PER_MICROSECOND (SystemCoreClock / 1000000) + void furi_hal_cortex_init_early() { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; @@ -13,11 +15,26 @@ void furi_hal_cortex_init_early() { void furi_hal_cortex_delay_us(uint32_t microseconds) { uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = SystemCoreClock / 1000000 * microseconds; + uint32_t time_ticks = FURI_HAL_CORTEX_INSTRUCTIONS_PER_MICROSECOND * microseconds; while((DWT->CYCCNT - start) < time_ticks) { }; } uint32_t furi_hal_cortex_instructions_per_microsecond() { - return SystemCoreClock / 1000000; + return FURI_HAL_CORTEX_INSTRUCTIONS_PER_MICROSECOND; } + +FuriHalCortexTimer furi_hal_cortex_timer_get(uint32_t timeout_us) { + FuriHalCortexTimer cortex_timer = {0}; + cortex_timer.start = DWT->CYCCNT; + cortex_timer.value = FURI_HAL_CORTEX_INSTRUCTIONS_PER_MICROSECOND * timeout_us; + return cortex_timer; +} + +bool furi_hal_cortex_timer_is_expired(FuriHalCortexTimer cortex_timer) { + return !((DWT->CYCCNT - cortex_timer.start) < cortex_timer.value); +} + +void furi_hal_cortex_timer_wait(FuriHalCortexTimer cortex_timer) { + while(!furi_hal_cortex_timer_is_expired(cortex_timer)); +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c.c b/firmware/targets/f7/furi_hal/furi_hal_i2c.c index 36f5230c2..6c17d6ade 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -60,11 +61,11 @@ bool furi_hal_i2c_tx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = furi_get_tick() + timeout; + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { ret = false; break; } @@ -89,7 +90,7 @@ bool furi_hal_i2c_tx( size--; } - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { ret = false; break; } @@ -111,11 +112,11 @@ bool furi_hal_i2c_rx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = furi_get_tick() + timeout; + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { ret = false; break; } @@ -140,7 +141,7 @@ bool furi_hal_i2c_rx( size--; } - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { ret = false; break; } @@ -175,11 +176,11 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = furi_get_tick() + timeout; + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { return false; } } @@ -190,14 +191,14 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, while((!LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) && (!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c))) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { return false; } } if(LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) { while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { return false; } } @@ -214,7 +215,7 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, } while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { return false; } } @@ -308,11 +309,11 @@ bool furi_hal_i2c_write_mem( bool ret = true; uint8_t size = len + 1; - uint32_t timeout_tick = furi_get_tick() + timeout; + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { ret = false; break; } @@ -341,7 +342,7 @@ bool furi_hal_i2c_write_mem( size--; } - if(furi_get_tick() >= timeout_tick) { + if(furi_hal_cortex_timer_is_expired(timer)) { ret = false; break; } diff --git a/firmware/targets/furi_hal_include/furi_hal_cortex.h b/firmware/targets/furi_hal_include/furi_hal_cortex.h index 13035161d..91596ffe3 100644 --- a/firmware/targets/furi_hal_include/furi_hal_cortex.h +++ b/firmware/targets/furi_hal_include/furi_hal_cortex.h @@ -6,11 +6,18 @@ #pragma once #include +#include #ifdef __cplusplus extern "C" { #endif +/** Cortex timer provides high precision low level expiring timer */ +typedef struct { + uint32_t start; + uint32_t value; +} FuriHalCortexTimer; + /** Early init stage for cortex */ void furi_hal_cortex_init_early(); @@ -27,6 +34,28 @@ void furi_hal_cortex_delay_us(uint32_t microseconds); */ uint32_t furi_hal_cortex_instructions_per_microsecond(); +/** Get Timer + * + * @param[in] timeout_us The expire timeout in us + * + * @return The FuriHalCortexTimer + */ +FuriHalCortexTimer furi_hal_cortex_timer_get(uint32_t timeout_us); + +/** Check if timer expired + * + * @param[in] cortex_timer The FuriHalCortexTimer + * + * @return true if expired + */ +bool furi_hal_cortex_timer_is_expired(FuriHalCortexTimer cortex_timer); + +/** Wait for timer expire + * + * @param[in] cortex_timer The FuriHalCortexTimer + */ +void furi_hal_cortex_timer_wait(FuriHalCortexTimer cortex_timer); + #ifdef __cplusplus } #endif