[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
This commit is contained in:
		
							parent
							
								
									f56c94922d
								
							
						
					
					
						commit
						33892ebfb7
					
				| @ -1,5 +1,5 @@ | |||||||
| entry,status,name,type,params | entry,status,name,type,params | ||||||
| Version,+,3.4,, | Version,+,3.5,, | ||||||
| Header,+,applications/services/bt/bt_service/bt.h,, | Header,+,applications/services/bt/bt_service/bt.h,, | ||||||
| Header,+,applications/services/cli/cli.h,, | Header,+,applications/services/cli/cli.h,, | ||||||
| Header,+,applications/services/cli/cli_vcp.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_delay_us,void,uint32_t | ||||||
| Function,-,furi_hal_cortex_init_early,void, | Function,-,furi_hal_cortex_init_early,void, | ||||||
| Function,+,furi_hal_cortex_instructions_per_microsecond,uint32_t, | 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_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_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t" | ||||||
| Function,-,furi_hal_crypto_init,void, | Function,-,furi_hal_crypto_init,void, | ||||||
|  | |||||||
| 
 | 
| @ -2,6 +2,8 @@ | |||||||
| 
 | 
 | ||||||
| #include <stm32wbxx.h> | #include <stm32wbxx.h> | ||||||
| 
 | 
 | ||||||
|  | #define FURI_HAL_CORTEX_INSTRUCTIONS_PER_MICROSECOND (SystemCoreClock / 1000000) | ||||||
|  | 
 | ||||||
| void furi_hal_cortex_init_early() { | void furi_hal_cortex_init_early() { | ||||||
|     CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; |     CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; | ||||||
|     DWT->CTRL |= DWT_CTRL_CYCCNTENA_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) { | void furi_hal_cortex_delay_us(uint32_t microseconds) { | ||||||
|     uint32_t start = DWT->CYCCNT; |     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) { |     while((DWT->CYCCNT - start) < time_ticks) { | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t furi_hal_cortex_instructions_per_microsecond() { | 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)); | ||||||
| } | } | ||||||
| @ -1,6 +1,7 @@ | |||||||
| #include <furi_hal_i2c.h> | #include <furi_hal_i2c.h> | ||||||
| #include <furi_hal_version.h> | #include <furi_hal_version.h> | ||||||
| #include <furi_hal_power.h> | #include <furi_hal_power.h> | ||||||
|  | #include <furi_hal_cortex.h> | ||||||
| 
 | 
 | ||||||
| #include <stm32wbxx_ll_i2c.h> | #include <stm32wbxx_ll_i2c.h> | ||||||
| #include <stm32wbxx_ll_gpio.h> | #include <stm32wbxx_ll_gpio.h> | ||||||
| @ -60,11 +61,11 @@ bool furi_hal_i2c_tx( | |||||||
|     furi_assert(timeout > 0); |     furi_assert(timeout > 0); | ||||||
| 
 | 
 | ||||||
|     bool ret = true; |     bool ret = true; | ||||||
|     uint32_t timeout_tick = furi_get_tick() + timeout; |     FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { |         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 ret = false; |                 ret = false; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -89,7 +90,7 @@ bool furi_hal_i2c_tx( | |||||||
|                 size--; |                 size--; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 ret = false; |                 ret = false; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -111,11 +112,11 @@ bool furi_hal_i2c_rx( | |||||||
|     furi_assert(timeout > 0); |     furi_assert(timeout > 0); | ||||||
| 
 | 
 | ||||||
|     bool ret = true; |     bool ret = true; | ||||||
|     uint32_t timeout_tick = furi_get_tick() + timeout; |     FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { |         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 ret = false; |                 ret = false; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -140,7 +141,7 @@ bool furi_hal_i2c_rx( | |||||||
|                 size--; |                 size--; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 ret = false; |                 ret = false; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -175,11 +176,11 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, | |||||||
|     furi_assert(timeout > 0); |     furi_assert(timeout > 0); | ||||||
| 
 | 
 | ||||||
|     bool ret = true; |     bool ret = true; | ||||||
|     uint32_t timeout_tick = furi_get_tick() + timeout; |     FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { |         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 return false; |                 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)) && |         while((!LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) && | ||||||
|               (!LL_I2C_IsActiveFlag_STOP(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; |                 return false; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if(LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) { |         if(LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) { | ||||||
|             while(!LL_I2C_IsActiveFlag_STOP(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; |                     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)) { |         while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -308,11 +309,11 @@ bool furi_hal_i2c_write_mem( | |||||||
| 
 | 
 | ||||||
|     bool ret = true; |     bool ret = true; | ||||||
|     uint8_t size = len + 1; |     uint8_t size = len + 1; | ||||||
|     uint32_t timeout_tick = furi_get_tick() + timeout; |     FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000); | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { |         while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 ret = false; |                 ret = false; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -341,7 +342,7 @@ bool furi_hal_i2c_write_mem( | |||||||
|                 size--; |                 size--; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if(furi_get_tick() >= timeout_tick) { |             if(furi_hal_cortex_timer_is_expired(timer)) { | ||||||
|                 ret = false; |                 ret = false; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -6,11 +6,18 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | /** Cortex timer provides high precision low level expiring timer */ | ||||||
|  | typedef struct { | ||||||
|  |     uint32_t start; | ||||||
|  |     uint32_t value; | ||||||
|  | } FuriHalCortexTimer; | ||||||
|  | 
 | ||||||
| /** Early init stage for cortex
 | /** Early init stage for cortex
 | ||||||
|  */ |  */ | ||||||
| void furi_hal_cortex_init_early(); | 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(); | 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 | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく