2018-02-14 02:41 AM
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-rcc2018-05-03 10:47 AM
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 callingHAL_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.