SWD debugging and changing Cortex M3 SYSCLK/HCLK speeds.
by OOjim » 12 Feb 2015 05:50
I have programmed my STM32F107VC to change its SYSCLK (and therefore also HCLK) speed to 72 MHz. Shortly after the frequency change takes effect, the debugger does a breakpoint (which I didn't set) and complains:
Program received signal SIGTRAP, Trace/breakpoint trap.
In ?? () ()
Failure finding "Stack level "
Failure matching reg_output
Failure finding "Stack level "
Failure matching reg_output
#2 enum_field<STM32F1::RCC_CFGR_SWS, unsigned long>::operator STM32F1::RCC_CFGR_SWS (this=0x80012d1) at C:\Cortex\src/bit_fields.h:142
C:\Cortex\src/bit_fields.h:142:5625:beg:0x8001d54
At C:\Cortex\src/bit_fields.h:142
What do I need to know about the relationship between the debugger and the Cortex clocks?
Re: SWD debugging and changing Cortex M3 SYSCLK/HCLK speeds.
by OOjim » 13 Feb 2015 21:13
I believe that my problem is FLASH wait states. This is from PM0075, the programming manual for flash on the STM32F10xxx, section 3.1
Bits 2:0 LATENCY: Latency
These bits represent the ratio of the SYSCLK (system clock) period to the Flash access time.
000 Zero wait state, if 0 < SYSCLK≤24 MHz
001 One wait state, if 24 MHz < SYSCLK ≤48 MHz
010 Two wait states, if 48 MHz < SYSCLK ≤72 MHz
Mismatching SYSCLK and the number of wait states will horribly confuse the debugger as accessed through SWD. Be sure to set the wait states BEFORE actually finalizing the change to SYSCLK.
I am setting the wait states properly when changing SYSCLK and the debugger is happy again.
int RCC::select_clock_source_and_verify (RCC_CFGR_SW source)
{
int timeout_count = 0;
const auto corresponding_SWS =
(source==RCC_CFGR_SW::PLL) ? RCC_CFGR_SWS::PLL :
(source==RCC_CFGR_SW::HSE) ? RCC_CFGR_SWS::HSE : RCC_CFGR_SWS::HSI;
// Set the number of FLASH waits states corresponding to the proposed SYSCLK frequency.
FLASH::instance().set_wait_states(SYSCLK_frequency(corresponding_SWS));
SW=source;
// The new clock speed should be in use. This will confuse the debugger unless the FLASH wait states are set.
while (SWS!=corresponding_SWS && ++timeout_count < timeout_maximum) ;
Re: SWD debugging and changing Cortex M3 SYSCLK/HCLK speeds.
by OOjim » 26 Feb 2015 01:06
I discover that it is difficult changing SYSCLK from 72 MHz to 8MHz, and thus changing FLASH wait states from 2 to 0. Unless done in the correct order, the debugger stops the program shortly after changing the wait states. Code: Select all
Contrary to what I thought earlier, it is best to change flash wait states soon after selecting the SYSTICK clock source...void RCC::select_clock_source_and_verify (RCC_CFGR_SWS source)
{
/* WARNING: This region has critical timing!
The changes to SYSCLK and the corresponding number of FLASH waits states
must be done in the proper order and (I suspect) within a short amount
of time.
Do not expect the debugger to reliably single step within this region.
*/
// To shorten the transition period, pre-calculate the new frequency.
const int next_frequency = SYSCLK_frequency(source);
FLASH& flash = FLASH::instance();
SWS=source;
// Set the number of FLASH waits states corresponding to the proposed SYSCLK frequency.
flash.set_wait_states(next_frequency);
// Wait, with timeout, for the corresponding ready indicator. Throw if it does not change as expected.
constexpr int timeout_subscript = RCC::SWS_DELAY;
rcc_delay_counts[timeout_subscript] = 0;
while (SWS!=source && ++rcc_delay_counts[timeout_subscript] < timeout_maximum) ;
if (rcc_delay_counts[timeout_subscript] >= timeout_maximum) throw_error ("SWS timeout in ", __func__ );
}
where SWS=source sets the SW field of RCC_CFGR for HSI, HSE, or PLL, and
set_wait_states sets the LATENCY field of FLASH_ACR to 0, 1, or 2.
Who is online
Users browsing this forum: No registered users and 2 guests