AnsweredAssumed Answered

STM32F3Discovery clock and sleeping issues

Question asked by goncharov.alexey on Oct 16, 2013
Latest reply on Oct 17, 2013 by Amel N
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 Clock configuration tool for STM32F30x/31x microcontrollers 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

Attachments

Outcomes