cancel
Showing results for 
Search instead for 
Did you mean: 

[bug report] In stm32f1xx_hal_rcc.c from STM32Cube_FW_F1_V1.6.0

ali maqsood
Associate
Posted on February 14, 2018 at 11:41

Hi, I have generated code for STM32F103C8T6 MCU in CubeMX. My clock setting is 72Mhz. The HAL_RCC_ClockConfig function always returns HAL_ERROR. Upon debuging I found the following code in this function which returns HAL_ERROR

#if defined(FLASH_ACR_LATENCY)
 /* Increasing the number of wait states because of higher CPU frequency */
 if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
 { 
 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
 __HAL_FLASH_SET_LATENCY(FLatency);
 
 /* Check that the new number of wait states is taken into account to access the Flash
 memory by reading the FLASH_ACR register */
 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
 {
 return HAL_ERROR;
 }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I thought it might be due to _HAL_FLASH_SET_LATENCY(FLatency) setting latency and immediately after that checking in FLASH->ACR if the latency has been set without waiting. So, I added a wait loop as following

#if defined(FLASH_ACR_LATENCY)
 /* Increasing the number of wait states because of higher CPU frequency */
 if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
 { 
 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
 __HAL_FLASH_SET_LATENCY(FLatency);
 
 for(uint32_t i=0; i<100; i++)
 {
 asm('nop');
 }
 /* Check that the new number of wait states is taken into account to access the Flash
 memory by reading the FLASH_ACR register */
 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
 {
 return HAL_ERROR;
 }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Now it works every time. Is this the correct solution? If so, kindly fix it.

Thank you

Regards

#stm32-f1-firmware #stm32cube_fw_f1_v1.6.0 #stm32-hal-driver #stm32-hal-rcc
1 REPLY 1
MDS
Associate III
Posted on May 03, 2018 at 19:47

I just encountered this problem, or very similar, on the STM32H7 NUCLEO board. I am using the fractional PLL multiplier to generate a system clock of 147456000 MHz. CubeMX calculated FLatency = 2. When the function

HAL_RCC_ClockConfig

(

)

is called, at around line #859 where the FLatency is changed from the startup value of 7 to the new value of 2, I get a hard fault (SIGINT), the board stops executing, and the debugger is dead. Here is the code with my fix:

/* Decreasing the number of wait states because of lower CPU frequency */

if

(

FLatency

< (

FLASH

->ACR &

FLASH_ACR_LATENCY

))

{

   

/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */

   

__HAL_FLASH_SET_LATENCY

(

FLatency

);

   

// FIX: Added delay executed from prefetch

   

__NOP

();

__NOP

();

__NOP

();

   

/* Check that the new number of wait states is taken into account to access the Flash memory by reading       the FLASH_ACR register */

 

if

((

FLASH

->ACR &

FLASH_ACR_LATENCY

) !=

FLatency

)

   {

   

return

HAL_ERROR;

   }

}

Before the fix, I discovered that breaking on the

line

__HAL_FLASH_SET_LATENCY

(

FLatency

) and just going again fixed the problem. Then I experimented with a delay using NOPs. Through experimentation, I discovered that in my case, I needed at least 3 NOPs to fix the problem (see above). I am guessing that it takes a few clocks for the new wait state value to stabilize.

Another, more bazar fix, is hard to explain or understand. After returning from the

SystemClock_Config

() call where the flash wait states are set, the main() program initializes all the peripherals. I am using many peripherals, but I noticed that

(without the fix above)

when I called MX_SPI3_INIT() and added 1 line of C code before calling

HAL_GPIO_Init

(

GPIOC

, &GPIO_InitStruct)

, the

FLatency

issue also went away. The only explanation for how code that has not executed yet can affect the current code execution may be some GCC tool optimization or bug. The real fix, as the originator of this thread has also discovered, is a delay after setting the FLASH wait states.