This is a RTC additional function. This is only for Nucleo F401RE & F411RE mbed(Added L152RE, F334R8, L476RG & F746xx). If you connected battery backup circuit for internal RTC, you can make a power-off and reset condition. RTC still has proper time and date.
Dependents: Nucleo_rtos_sample PB_Emma_Ethernet
Please refer following NOTE information.
/users/kenjiArai/notebook/nucleo-series-rtc-control-under-power-onoff-and-re/
Diff: SetRTC.cpp
- Revision:
- 2:765470eab2a6
- Parent:
- 0:e4c20fd769f1
- Child:
- 5:1a8e7aed053d
diff -r e4c20fd769f1 -r 765470eab2a6 SetRTC.cpp --- a/SetRTC.cpp Sat Feb 07 02:19:57 2015 +0000 +++ b/SetRTC.cpp Mon Feb 16 12:33:22 2015 +0000 @@ -7,7 +7,7 @@ * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: October 24th, 2014 - * Revised: Feburary 7th, 2015 + * Revised: Feburary 16th, 2015 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE @@ -54,6 +54,7 @@ static uint32_t check_RTC_backup_reg( void ); static int xatoi (char **str, unsigned long *res); static void get_line (char *buff, int len); +static void set_5v_drop_detect(void); //------------------------------------------------------------------------------------------------- // Control Program @@ -61,6 +62,7 @@ int32_t SetRTC() { if (rtc_external_osc_init() == OK) { + set_5v_drop_detect(); return OK; } else { return NG; @@ -306,7 +308,6 @@ pcr.putc('\n'); } - // RTC related subroutines void chk_and_set_time(char *ptr) { @@ -340,7 +341,7 @@ // Show Time with several example // ex.1 pcr.printf("Date: %04d/%02d/%02d, %02d:%02d:%02d\r\n", - t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); #if 0 time_t seconds; char buf[40]; @@ -373,7 +374,113 @@ chk_and_set_time(ptr); } +#if defined(TARGET_NUCLEO_L152RE) +void deepsleep_preparation(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + RCC->AHBENR |= (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | + RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOHEN); + // All other ports are analog input mode + GPIO_InitStruct.Pin = GPIO_PIN_All; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + RCC->AHBENR &= ~(RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | + RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOHEN); + while(1) { + HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); + } +} #else +void deepsleep_preparation(void) +{ + ; // No implementation +} +#endif + +#if defined(TARGET_NUCLEO_L152RE) +#if defined(USE_IRQ_FOR_RTC_BKUP) +// COMP2 Interrupt routine +void irq_comp2_handler(void) +{ + __disable_irq(); + deepsleep_preparation(); +} + +COMP_HandleTypeDef COMP_HandleStruct; +GPIO_InitTypeDef GPIO_InitStruct; + +void set_BOR_level2(void) +{ + FLASH_OBProgramInitTypeDef my_flash; + + HAL_FLASHEx_OBGetConfig(&my_flash); // read current configuration + if (my_flash.BORLevel != OB_BOR_LEVEL2) { + my_flash.BORLevel = OB_BOR_LEVEL2; + HAL_FLASHEx_OBProgram(&my_flash); + } +} + +void set_5v_drop_detect(void) +{ + // Set BOR level2 (2.30 to 2.49V) + set_BOR_level2(); + // Set Analog voltage input (PB5 or PB6) +#if defined(USE_PB5_FOR_COMP) + GPIO_InitStruct.Pin = GPIO_PIN_5; // PB5 comp input +#elif defined(USE_PB6_FOR_COMP) + GPIO_InitStruct.Pin = GPIO_PIN_6; // PB6 comp input +#else +#error "Please define USE_PB5_FOR_COMP or USE_PB6_FOR_COMP in SetRTC.h" +#endif + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + // COMP2 sets for low volatage detection + __COMP_CLK_ENABLE(); + COMP_HandleStruct.Instance = COMP2; + COMP_HandleStruct.Init.InvertingInput = COMP_INVERTINGINPUT_VREFINT; +#if defined(USE_PB5_FOR_COMP) + COMP_HandleStruct.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_PB5; +#elif defined(USE_PB6_FOR_COMP) + COMP_HandleStruct.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_PB6; +#endif + COMP_HandleStruct.Init.Output = COMP_OUTPUT_NONE; + COMP_HandleStruct.Init.Mode = COMP_MODE_HIGHSPEED; + COMP_HandleStruct.Init.WindowMode = COMP_WINDOWMODE_DISABLED; + //COMP_HandleStruct.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING; + COMP_HandleStruct.Init.TriggerMode = COMP_TRIGGERMODE_IT_FALLING; + HAL_COMP_Init(&COMP_HandleStruct); + // Interrupt configuration + NVIC_SetVector(COMP_IRQn, (uint32_t)irq_comp2_handler); +// HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); + HAL_NVIC_SetPriority(COMP_IRQn, 0, 0); + HAL_NVIC_ClearPendingIRQ(COMP_IRQn); + HAL_COMP_Start_IT(&COMP_HandleStruct); + HAL_NVIC_EnableIRQ(COMP_IRQn); +} +#else // defined(USE_IRQ_FOR_RTC_BKUP) +void set_5v_drop_detect(void) +{ + ; // No implementation +} +#endif // defined(USE_IRQ_FOR_RTC_BKUP) + +#else // defined(TARGET_NUCLEO_L152RE) +void set_5v_drop_detect(void) +{ + ; // No implementation +} +#endif // defined(TARGET_NUCLEO_L152RE) + +#else // defined(TARGET_NUCLEO_F401RE,TARGET_NUCLEO_F411RE,TARGET_NUCLEO_L152RE) #error "No suport this mbed, only for Nucleo mbed" -#endif -// defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE) +#endif // defined(TARGET_NUCLEO_F401RE,TARGET_NUCLEO_F411RE,TARGET_NUCLEO_L152RE)