mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-23 13:21:44 +03:00
FuriHal: add flash ops stats, workaround bug in SHCI_C2_SetSystemClock (#3657)
* FuriHal: add flash ops stats, workaround bug in SHCI_C2_SetSystemClock * hal: flash: added FLASH_OP_DEBUG to enable latency measurement Co-authored-by: hedger <hedger@nanode.su> Co-authored-by: hedger <hedger@users.noreply.github.com>
This commit is contained in:
parent
9e42e00ead
commit
e0797131ec
@ -133,7 +133,7 @@ void furi_hal_clock_switch_hse2hsi(void) {
|
||||
;
|
||||
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
|
||||
furi_assert(LL_RCC_GetSMPSClockSelection() == LL_RCC_SMPS_CLKSOURCE_HSI);
|
||||
furi_check(LL_RCC_GetSMPSClockSelection() == LL_RCC_SMPS_CLKSOURCE_HSI);
|
||||
|
||||
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
|
||||
;
|
||||
@ -170,7 +170,7 @@ void furi_hal_clock_switch_hsi2hse(void) {
|
||||
}
|
||||
|
||||
bool furi_hal_clock_switch_hse2pll(void) {
|
||||
furi_assert(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
furi_check(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
|
||||
LL_RCC_PLL_Enable();
|
||||
LL_RCC_PLLSAI1_Enable();
|
||||
@ -180,12 +180,13 @@ bool furi_hal_clock_switch_hse2pll(void) {
|
||||
while(!LL_RCC_PLLSAI1_IsReady())
|
||||
;
|
||||
|
||||
if(SHCI_C2_SetSystemClock(SET_SYSTEM_CLOCK_HSE_TO_PLL) != SHCI_Success) {
|
||||
// This API returns garbage if stack version < 1.20.0
|
||||
SHCI_C2_SetSystemClock(SET_SYSTEM_CLOCK_HSE_TO_PLL);
|
||||
// So we'll check results by asking hardware directly
|
||||
if(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
furi_check(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
|
||||
|
||||
LL_SetSystemCoreClock(CPU_CLOCK_PLL_HZ);
|
||||
SysTick->LOAD = (uint32_t)((SystemCoreClock / 1000) - 1UL);
|
||||
|
||||
@ -193,18 +194,19 @@ bool furi_hal_clock_switch_hse2pll(void) {
|
||||
}
|
||||
|
||||
bool furi_hal_clock_switch_pll2hse(void) {
|
||||
furi_assert(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
|
||||
furi_check(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
|
||||
|
||||
LL_RCC_HSE_Enable();
|
||||
while(!LL_RCC_HSE_IsReady())
|
||||
;
|
||||
|
||||
if(SHCI_C2_SetSystemClock(SET_SYSTEM_CLOCK_PLL_ON_TO_HSE) != SHCI_Success) {
|
||||
// This API returns garbage if stack version < 1.20.0
|
||||
SHCI_C2_SetSystemClock(SET_SYSTEM_CLOCK_PLL_ON_TO_HSE);
|
||||
// So we'll check results by asking hardware directly
|
||||
if(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
furi_check(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
|
||||
LL_SetSystemCoreClock(CPU_CLOCK_HSE_HZ);
|
||||
SysTick->LOAD = (uint32_t)((SystemCoreClock / 1000) - 1UL);
|
||||
|
||||
|
@ -16,6 +16,12 @@
|
||||
|
||||
#define TAG "FuriHalFlash"
|
||||
|
||||
#ifdef FLASH_OP_DEBUG
|
||||
#undef FURI_LOG_T
|
||||
#define FURI_LOG_T(...)
|
||||
#else
|
||||
#endif
|
||||
|
||||
#define FURI_HAL_CRITICAL_MSG "Critical flash operation fail"
|
||||
#define FURI_HAL_FLASH_READ_BLOCK (8U)
|
||||
#define FURI_HAL_FLASH_WRITE_BLOCK (8U)
|
||||
@ -291,6 +297,7 @@ bool furi_hal_flash_wait_last_operation(uint32_t timeout) {
|
||||
}
|
||||
|
||||
void furi_hal_flash_erase(uint8_t page) {
|
||||
uint32_t op_stat = DWT->CYCCNT;
|
||||
furi_hal_flash_begin(true);
|
||||
|
||||
/* Ensure that controller state is valid */
|
||||
@ -313,6 +320,12 @@ void furi_hal_flash_erase(uint8_t page) {
|
||||
furi_hal_flush_cache();
|
||||
|
||||
furi_hal_flash_end(true);
|
||||
op_stat = DWT->CYCCNT - op_stat;
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"erase took %lu clocks or %fus",
|
||||
op_stat,
|
||||
(double)((float)op_stat / (float)furi_hal_cortex_instructions_per_microsecond()));
|
||||
}
|
||||
|
||||
static inline void furi_hal_flash_write_dword_internal_nowait(size_t address, uint64_t* data) {
|
||||
@ -335,6 +348,7 @@ static inline void furi_hal_flash_write_dword_internal(size_t address, uint64_t*
|
||||
}
|
||||
|
||||
void furi_hal_flash_write_dword(size_t address, uint64_t data) {
|
||||
uint32_t op_stat = DWT->CYCCNT;
|
||||
furi_hal_flash_begin(false);
|
||||
|
||||
/* Ensure that controller state is valid */
|
||||
@ -357,6 +371,12 @@ void furi_hal_flash_write_dword(size_t address, uint64_t data) {
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT));
|
||||
op_stat = DWT->CYCCNT - op_stat;
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"write_dword took %lu clocks or %fus",
|
||||
op_stat,
|
||||
(double)((float)op_stat / (float)furi_hal_cortex_instructions_per_microsecond()));
|
||||
}
|
||||
|
||||
static size_t furi_hal_flash_get_page_address(uint8_t page) {
|
||||
@ -369,6 +389,7 @@ void furi_hal_flash_program_page(const uint8_t page, const uint8_t* data, uint16
|
||||
|
||||
furi_hal_flash_erase(page);
|
||||
|
||||
uint32_t op_stat = DWT->CYCCNT;
|
||||
furi_hal_flash_begin(false);
|
||||
|
||||
furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT));
|
||||
@ -428,6 +449,12 @@ void furi_hal_flash_program_page(const uint8_t page, const uint8_t* data, uint16
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
|
||||
furi_hal_flash_end(false);
|
||||
op_stat = DWT->CYCCNT - op_stat;
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"program_page took %lu clocks or %fus",
|
||||
op_stat,
|
||||
(double)((float)op_stat / (float)furi_hal_cortex_instructions_per_microsecond()));
|
||||
}
|
||||
|
||||
int16_t furi_hal_flash_get_page_number(size_t address) {
|
||||
|
Loading…
Reference in New Issue
Block a user