cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3Discovery clock and sleeping issues

alexygoncharov
Associate II
Posted on October 16, 2013 at 10:11

Hello everyone!

Now I'm playing with STM32F3Discovery which has STM32F303 on the board. The goal for this MCU is typical: do some gpio stuff -> sleep for a while (STOP mode) -> wake up -> gpio. There is also one more requirement for the MCU: It has to work @1 MHz. I used

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1533/PF258143

and finally got the file system_stm32f30x.c, which you may find in the attach to this post. To be sure that system starts up I added some code to SysTick_Handler:

void
SysTick_Handler( 
void
)
{
STM_EVAL_LEDToggle( LED10 );
systick_event = 1;
}

After some testing I've figured out that if HCLK frequency is less than 4 MHz then LED doesn't toggle at all. So I guess that system doesn't start in this case. Here is my first question: Is it possible (and how if yes) to run STM32F303 at HCLK = 1 MHz? If HCLK >= 4 MHz then led toggles and system starts without any problem till first sleeping. Here is the code to prepare the MCU to go to sleep:

void
prepare_for_sleep()
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

 

/* ALARM Configuration ****************************************************/
/* Set alarm in 5s */
/* EXTI configuration */
EXTI_ClearITPendingBit( EXTI_Line17 );
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init( &EXTI_InitStructure );
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
/* Get current time */
RTC_GetTime( RTC_Format_BIN, &RTC_TimeStructure );
/* Set the alarm to current time + 5s */
RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x31;
RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay |
RTC_AlarmMask_Minutes |
RTC_AlarmMask_Hours;
RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = RTC_TimeStructure.RTC_Hours;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = RTC_TimeStructure.RTC_Minutes;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = RTC_TimeStructure.RTC_Seconds + 15;
if
( RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds >= 60 )
{
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds -= 60;
if
( ++RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes >= 60 )
{
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes -= 60;
if
( ++RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours > 12 )
RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = 1;
}
}
RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure );
/* Enable the RTC Alarm A interrupt */
RTC_ITConfig( RTC_IT_ALRA, ENABLE );
/* Enable the alarm */
RTC_AlarmCmd( RTC_Alarm_A, ENABLE );
/* Clear the Alarm A Pending Bit */
RTC_ClearITPendingBit( RTC_IT_ALRA );
/* LEDs Off */
STM_EVAL_LEDOff( LED3 );
STM_EVAL_LEDOff( LED4 );
STM_EVAL_LEDOff( LED5 );
STM_EVAL_LEDOff( LED6 );
STM_EVAL_LEDOff( LED7 );
STM_EVAL_LEDOff( LED8 );
STM_EVAL_LEDOff( LED9 );
STM_EVAL_LEDOff( LED10 );
USART_ITConfig( USART1, USART_IT_RXNE, DISABLE );
USART_ITConfig( USART2, USART_IT_RXNE, DISABLE );
/* Request to enter STOP mode with regulator in low power mode */
PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_STOPEntry_WFI );
}

You may figure out that the system sleeps for 15 seconds and then wakes up. The code which is being executed right after waking up is listed below:

void
wake_up()
{
RCC_HSEConfig( RCC_HSE_ON );
ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
FLASH_PrefetchBufferCmd( ENABLE );
FLASH_SetLatency(FLASH_Latency_0);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_PLLConfig(RCC_PREDIV1_Div4, RCC_PLLMul_2);
RCC_PLLCmd(ENABLE);
while
( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET ) {}
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
while
( RCC_GetSYSCLKSource() != 0x08 ) {}
RTC_ITConfig( RTC_IT_ALRA, DISABLE );
RTC_AlarmCmd( RTC_Alarm_A, DISABLE );
}

Right after first wake up the led mentioned before is blinking. But the blinking rate, in particular, and, for example, UART timings become different (if compare with the same before sleeping). So I guess that I'm doing something wrong before or after waking up. Here is my second question: what is the right way to wake up and reinitialize MCU clock subsystem? Thank you in advance
1 REPLY 1
Amel NASRI
ST Employee
Posted on October 17, 2013 at 12:20

Hi Alexey,

Is it possible (and how if yes) to run STM32F303 at HCLK = 1 MHz?

==> Yes this is possible. If you are using a HSE=8MHz, add this code:

RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV8;

You can check the exact system clocking by configuring the MCO pin to output clock value.

what is the right way to wake up and reinitialize MCU clock subsystem?

In the wakeup function, you are re-configuring clocks. If you need same configuration as before entering stop mode, avoid such re-configuration.

Also, RTC clock source should be LSE or LSI. Is it the case in your example?

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.