Skip to content

Commit

Permalink
FuriHal: add flash ops stats, workaround bug in SHCI_C2_SetSystemClock (
Browse files Browse the repository at this point in the history
flipperdevices#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 <[email protected]>
Co-authored-by: hedger <[email protected]>
  • Loading branch information
3 people authored May 20, 2024
1 parent 9e42e00 commit e079713
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
20 changes: 11 additions & 9 deletions targets/f7/furi_hal/furi_hal_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
;
Expand Down Expand Up @@ -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();
Expand All @@ -180,31 +180,33 @@ 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);

return true;
}

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);

Expand Down
27 changes: 27 additions & 0 deletions targets/f7/furi_hal/furi_hal_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand All @@ -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) {
Expand All @@ -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 */
Expand All @@ -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) {
Expand All @@ -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));
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit e079713

Please sign in to comment.