mirror of https://github.com/ARMmbed/mbed-os.git
200 lines
6.5 KiB
C
200 lines
6.5 KiB
C
/* mbed Microcontroller Library
|
|
*******************************************************************************
|
|
* Copyright (c) 2014, STMicroelectronics
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*******************************************************************************
|
|
*/
|
|
#include "rtc_api.h"
|
|
|
|
#if DEVICE_RTC
|
|
|
|
#include "mbed_error.h"
|
|
|
|
static int rtc_inited = 0;
|
|
|
|
static RTC_HandleTypeDef RtcHandle;
|
|
|
|
void rtc_init(void)
|
|
{
|
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
|
|
|
if (rtc_inited) return;
|
|
rtc_inited = 1;
|
|
|
|
RtcHandle.Instance = RTC;
|
|
|
|
#if !RTC_LSI
|
|
// Enable LSE Oscillator
|
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
|
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
|
|
RCC_OscInitStruct.LSEState = RCC_LSE_ON; // External 32.768 kHz clock on OSC_IN/OSC_OUT
|
|
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
|
|
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { // Check if LSE has started correctly
|
|
// Connect LSE to RTC
|
|
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
|
|
} else {
|
|
error("Cannot initialize RTC with LSE\n");
|
|
}
|
|
#else
|
|
// Enable Power clock
|
|
__HAL_RCC_PWR_CLK_ENABLE();
|
|
|
|
// Enable access to Backup domain
|
|
HAL_PWR_EnableBkUpAccess();
|
|
|
|
// Reset Backup domain
|
|
__HAL_RCC_BACKUPRESET_FORCE();
|
|
__HAL_RCC_BACKUPRESET_RELEASE();
|
|
|
|
// Enable LSI clock
|
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
|
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
|
|
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
|
|
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
|
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
|
|
error("Cannot initialize RTC with LSI\n");
|
|
}
|
|
// Connect LSI to RTC
|
|
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
|
|
// This value is LSI typical value. To be measured precisely using a timer input capture for example.
|
|
#endif
|
|
|
|
// Enable RTC
|
|
__HAL_RCC_RTC_ENABLE();
|
|
|
|
RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
|
|
|
|
if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
|
|
error("RTC error: RTC initialization failed.");
|
|
}
|
|
}
|
|
|
|
void rtc_free(void)
|
|
{
|
|
#if RTC_LSI
|
|
// Enable Power clock
|
|
__PWR_CLK_ENABLE();
|
|
|
|
// Enable access to Backup domain
|
|
HAL_PWR_EnableBkUpAccess();
|
|
|
|
// Reset Backup domain
|
|
__HAL_RCC_BACKUPRESET_FORCE();
|
|
__HAL_RCC_BACKUPRESET_RELEASE();
|
|
|
|
// Disable access to Backup domain
|
|
HAL_PWR_DisableBkUpAccess();
|
|
#endif
|
|
|
|
// Disable LSI and LSE clocks
|
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
|
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
|
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
|
|
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
|
|
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
|
|
|
rtc_inited = 0;
|
|
}
|
|
|
|
int rtc_isenabled(void)
|
|
{
|
|
return rtc_inited;
|
|
}
|
|
|
|
/*
|
|
RTC Registers
|
|
RTC_WeekDay 1=monday, 2=tuesday, ..., 7=sunday
|
|
RTC_Month 1=january, 2=february, ..., 12=december
|
|
RTC_Date day of the month 1-31
|
|
RTC_Year year 0-99
|
|
struct tm
|
|
tm_sec seconds after the minute 0-61
|
|
tm_min minutes after the hour 0-59
|
|
tm_hour hours since midnight 0-23
|
|
tm_mday day of the month 1-31
|
|
tm_mon months since January 0-11
|
|
tm_year years since 1900
|
|
tm_wday days since Sunday 0-6
|
|
tm_yday days since January 1 0-365
|
|
tm_isdst Daylight Saving Time flag
|
|
*/
|
|
time_t rtc_read(void)
|
|
{
|
|
RTC_DateTypeDef dateStruct;
|
|
RTC_TimeTypeDef timeStruct;
|
|
struct tm timeinfo;
|
|
|
|
RtcHandle.Instance = RTC;
|
|
|
|
// Read actual date and time
|
|
// Warning: the time must be read first!
|
|
HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
|
|
HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
|
|
|
|
// Setup a tm structure based on the RTC
|
|
timeinfo.tm_wday = dateStruct.WeekDay;
|
|
timeinfo.tm_mon = dateStruct.Month - 1;
|
|
timeinfo.tm_mday = dateStruct.Date;
|
|
timeinfo.tm_year = dateStruct.Year;
|
|
timeinfo.tm_hour = timeStruct.Hours;
|
|
timeinfo.tm_min = timeStruct.Minutes;
|
|
timeinfo.tm_sec = timeStruct.Seconds;
|
|
// Daylight Saving Time information is not available
|
|
timeinfo.tm_isdst = -1;
|
|
|
|
// Convert to timestamp
|
|
time_t t = mktime(&timeinfo);
|
|
|
|
return t;
|
|
}
|
|
|
|
void rtc_write(time_t t)
|
|
{
|
|
RTC_DateTypeDef dateStruct;
|
|
RTC_TimeTypeDef timeStruct;
|
|
|
|
RtcHandle.Instance = RTC;
|
|
|
|
// Convert the time into a tm
|
|
struct tm *timeinfo = localtime(&t);
|
|
|
|
// Fill RTC structures
|
|
dateStruct.WeekDay = timeinfo->tm_wday;
|
|
dateStruct.Month = timeinfo->tm_mon + 1;
|
|
dateStruct.Date = timeinfo->tm_mday;
|
|
dateStruct.Year = timeinfo->tm_year;
|
|
timeStruct.Hours = timeinfo->tm_hour;
|
|
timeStruct.Minutes = timeinfo->tm_min;
|
|
timeStruct.Seconds = timeinfo->tm_sec;
|
|
|
|
// Change the RTC current date/time
|
|
HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
|
|
HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
|
|
}
|
|
|
|
#endif
|