mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #4499 from c1728p9/fix_rtc_api_time_conversion
Fix rtc api time conversionpull/4478/head^2
commit
434787b9a8
|
@ -0,0 +1,245 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
|
||||
#include "mbed.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
/*
|
||||
* regular is_leap_year, see platform/mbed_mktime.c for the optimized version
|
||||
*/
|
||||
bool is_leap_year(int year) {
|
||||
year = 1900 + year;
|
||||
if (year % 4) {
|
||||
return false;
|
||||
} else if (year % 100) {
|
||||
return true;
|
||||
} else if (year % 400) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the optimized version of _rtc_is_leap_year against the generic version.
|
||||
*/
|
||||
void test_is_leap_year() {
|
||||
for (int i = 70; i < 138; ++i) {
|
||||
bool expected = is_leap_year(i);
|
||||
bool actual_value = _rtc_is_leap_year(i);
|
||||
|
||||
if (expected != actual_value) {
|
||||
printf ("leap year failed with i = %d\r\n", i);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(expected, actual_value);
|
||||
}
|
||||
}
|
||||
|
||||
struct tm make_time_info(int year, int month, int day, int hours, int minutes, int seconds) {
|
||||
struct tm timeinfo;
|
||||
timeinfo.tm_year = year;
|
||||
timeinfo.tm_mon = month;
|
||||
timeinfo.tm_mday = day;
|
||||
timeinfo.tm_hour = hours;
|
||||
timeinfo.tm_min = minutes;
|
||||
timeinfo.tm_sec = seconds;
|
||||
return timeinfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* test out of range values for _rtc_mktime.
|
||||
* The function operates from the 1st of january 1970 at 00:00:00 to the 19th
|
||||
* of january 2038 at 03:14:07.
|
||||
*/
|
||||
void test_mk_time_out_of_range() {
|
||||
tm invalid_lower_bound = make_time_info(
|
||||
69,
|
||||
11,
|
||||
31,
|
||||
23,
|
||||
59,
|
||||
59
|
||||
);
|
||||
|
||||
tm valid_lower_bound = make_time_info(
|
||||
70,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
tm valid_upper_bound = make_time_info(
|
||||
138,
|
||||
0,
|
||||
19,
|
||||
3,
|
||||
14,
|
||||
7
|
||||
);
|
||||
|
||||
tm invalid_upper_bound = make_time_info(
|
||||
138,
|
||||
0,
|
||||
19,
|
||||
3,
|
||||
14,
|
||||
8
|
||||
);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(((time_t) -1), _rtc_mktime(&invalid_lower_bound));
|
||||
TEST_ASSERT_EQUAL_INT(((time_t) 0), _rtc_mktime(&valid_lower_bound));
|
||||
TEST_ASSERT_EQUAL_INT(((time_t) INT_MAX), _rtc_mktime(&valid_upper_bound));
|
||||
TEST_ASSERT_EQUAL_INT(((time_t) -1), _rtc_mktime(&invalid_upper_bound));
|
||||
}
|
||||
|
||||
/*
|
||||
* test mktime over a large set of values
|
||||
*/
|
||||
void test_mk_time() {
|
||||
for (size_t year = 70; year < 137; ++year) {
|
||||
for (size_t month = 0; month < 12; ++month) {
|
||||
for (size_t day = 1; day < 32; ++day) {
|
||||
if (month == 1 && is_leap_year(year) && day == 29) {
|
||||
break;
|
||||
} else if(month == 1 && !is_leap_year(year) && day == 28) {
|
||||
break;
|
||||
} else if (
|
||||
day == 31 &&
|
||||
(month == 3 || month == 5 || month == 8 || month == 10)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t hour = 0; hour < 24; ++hour) {
|
||||
tm time_info = make_time_info(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
hour % 2 ? 59 : 0,
|
||||
hour % 2 ? 59 : 0
|
||||
);
|
||||
|
||||
time_t expected = mktime(&time_info);
|
||||
time_t actual_value = _rtc_mktime(&time_info);
|
||||
|
||||
char msg[128] = "";
|
||||
if (expected != actual_value) {
|
||||
snprintf(
|
||||
msg, sizeof(msg),
|
||||
"year = %d, month = %d, day = %d, diff = %ld",
|
||||
year, month, day, expected - actual_value
|
||||
);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual_value, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* test value out of range for localtime
|
||||
*/
|
||||
void test_local_time_limit() {
|
||||
struct tm dummy_value;
|
||||
TEST_ASSERT_FALSE(_rtc_localtime((time_t) -1, &dummy_value));
|
||||
TEST_ASSERT_FALSE(_rtc_localtime((time_t) INT_MIN, &dummy_value));
|
||||
}
|
||||
|
||||
/*
|
||||
* test _rtc_localtime over a large set of values.
|
||||
*/
|
||||
void test_local_time() {
|
||||
for (uint32_t i = 0; i < INT_MAX; i += 3451) {
|
||||
time_t copy = (time_t) i;
|
||||
struct tm* expected = localtime(©);
|
||||
struct tm actual_value;
|
||||
bool result = _rtc_localtime((time_t) i, &actual_value);
|
||||
|
||||
if (
|
||||
expected->tm_sec != actual_value.tm_sec ||
|
||||
expected->tm_min != actual_value.tm_min ||
|
||||
expected->tm_hour != actual_value.tm_hour ||
|
||||
expected->tm_mday != actual_value.tm_mday ||
|
||||
expected->tm_mon != actual_value.tm_mon ||
|
||||
expected->tm_year != actual_value.tm_year ||
|
||||
expected->tm_wday != actual_value.tm_wday ||
|
||||
expected->tm_yday != actual_value.tm_yday ||
|
||||
result == false
|
||||
) {
|
||||
printf("error: i = %lu\r\n", i);
|
||||
}
|
||||
|
||||
TEST_ASSERT_TRUE(result);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_sec, actual_value.tm_sec, "invalid seconds"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_min, actual_value.tm_min, "invalid minutes"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_hour, actual_value.tm_hour, "invalid hours"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_mday, actual_value.tm_mday, "invalid day"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_mon, actual_value.tm_mon, "invalid month"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_year, actual_value.tm_year, "invalid year"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_wday, actual_value.tm_wday, "invalid weekday"
|
||||
);
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(
|
||||
expected->tm_yday, actual_value.tm_yday, "invalid year day"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
|
||||
greentea_case_failure_abort_handler(source, reason);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("test is leap year", test_is_leap_year, greentea_failure_handler),
|
||||
Case("test mk time out of range values", test_mk_time_out_of_range, greentea_failure_handler),
|
||||
Case("mk time", test_mk_time, greentea_failure_handler),
|
||||
Case("test local time", test_local_time, greentea_failure_handler),
|
||||
Case("test local time limits", test_local_time_limit, greentea_failure_handler),
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
|
||||
GREENTEA_SETUP(1200, "default_auto");
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
||||
int main() {
|
||||
return Harness::run(specification);
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
/*
|
||||
* time constants
|
||||
*/
|
||||
#define SECONDS_BY_MINUTES 60
|
||||
#define MINUTES_BY_HOUR 60
|
||||
#define SECONDS_BY_HOUR (SECONDS_BY_MINUTES * MINUTES_BY_HOUR)
|
||||
#define HOURS_BY_DAY 24
|
||||
#define SECONDS_BY_DAY (SECONDS_BY_HOUR * HOURS_BY_DAY)
|
||||
|
||||
/*
|
||||
* 2 dimensional array containing the number of seconds elapsed before a given
|
||||
* month.
|
||||
* The second index map to the month while the first map to the type of year:
|
||||
* - 0: non leap year
|
||||
* - 1: leap year
|
||||
*/
|
||||
static const uint32_t seconds_before_month[2][12] = {
|
||||
{
|
||||
0,
|
||||
31 * SECONDS_BY_DAY,
|
||||
(31 + 28) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31 + 30) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * SECONDS_BY_DAY,
|
||||
},
|
||||
{
|
||||
0,
|
||||
31 * SECONDS_BY_DAY,
|
||||
(31 + 29) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31 + 30) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31 + 30 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31 + 30 + 31 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) * SECONDS_BY_DAY,
|
||||
(31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * SECONDS_BY_DAY,
|
||||
}
|
||||
};
|
||||
|
||||
bool _rtc_is_leap_year(int year) {
|
||||
/*
|
||||
* since in practice, the value manipulated by this algorithm lie in the
|
||||
* range [70 : 138], the algorith can be reduced to: year % 4.
|
||||
* The algorithm valid over the full range of value is:
|
||||
|
||||
year = 1900 + year;
|
||||
if (year % 4) {
|
||||
return false;
|
||||
} else if (year % 100) {
|
||||
return true;
|
||||
} else if (year % 400) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
*/
|
||||
return (year) % 4 ? false : true;
|
||||
}
|
||||
|
||||
time_t _rtc_mktime(const struct tm* time) {
|
||||
// partial check for the upper bound of the range
|
||||
// normalization might happen at the end of the function
|
||||
// this solution is faster than checking if the input is after the 19th of
|
||||
// january 2038 at 03:14:07.
|
||||
if ((time->tm_year < 70) || (time->tm_year > 138)) {
|
||||
return ((time_t) -1);
|
||||
}
|
||||
|
||||
uint32_t result = time->tm_sec;
|
||||
result += time->tm_min * SECONDS_BY_MINUTES;
|
||||
result += time->tm_hour * SECONDS_BY_HOUR;
|
||||
result += (time->tm_mday - 1) * SECONDS_BY_DAY;
|
||||
result += seconds_before_month[_rtc_is_leap_year(time->tm_year)][time->tm_mon];
|
||||
|
||||
if (time->tm_year > 70) {
|
||||
// valid in the range [70:138]
|
||||
uint32_t count_of_leap_days = ((time->tm_year - 1) / 4) - (70 / 4);
|
||||
result += (((time->tm_year - 70) * 365) + count_of_leap_days) * SECONDS_BY_DAY;
|
||||
}
|
||||
|
||||
if (result > INT32_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool _rtc_localtime(time_t timestamp, struct tm* time_info) {
|
||||
if (((int32_t) timestamp) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
time_info->tm_sec = timestamp % 60;
|
||||
timestamp = timestamp / 60; // timestamp in minutes
|
||||
time_info->tm_min = timestamp % 60;
|
||||
timestamp = timestamp / 60; // timestamp in hours
|
||||
time_info->tm_hour = timestamp % 24;
|
||||
timestamp = timestamp / 24; // timestamp in days;
|
||||
|
||||
// compute the weekday
|
||||
// The 1st of January 1970 was a Thursday which is equal to 4 in the weekday
|
||||
// representation ranging from [0:6]
|
||||
time_info->tm_wday = (timestamp + 4) % 7;
|
||||
|
||||
// years start at 70
|
||||
time_info->tm_year = 70;
|
||||
while (true) {
|
||||
if (_rtc_is_leap_year(time_info->tm_year) && timestamp >= 366) {
|
||||
++time_info->tm_year;
|
||||
timestamp -= 366;
|
||||
} else if (!_rtc_is_leap_year(time_info->tm_year) && timestamp >= 365) {
|
||||
++time_info->tm_year;
|
||||
timestamp -= 365;
|
||||
} else {
|
||||
// the remaining days are less than a years
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
time_info->tm_yday = timestamp;
|
||||
|
||||
// convert days into seconds and find the current month
|
||||
timestamp *= SECONDS_BY_DAY;
|
||||
time_info->tm_mon = 11;
|
||||
bool leap = _rtc_is_leap_year(time_info->tm_year);
|
||||
for (uint32_t i = 0; i < 12; ++i) {
|
||||
if ((uint32_t) timestamp < seconds_before_month[leap][i]) {
|
||||
time_info->tm_mon = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove month from timestamp and compute the number of days.
|
||||
// note: unlike other fields, days are not 0 indexed.
|
||||
timestamp -= seconds_before_month[leap][time_info->tm_mon];
|
||||
time_info->tm_mday = (timestamp / SECONDS_BY_DAY) + 1;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
|
||||
/** \addtogroup platform */
|
||||
/** @{*/
|
||||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBED_MKTIME_H
|
||||
#define MBED_MKTIME_H
|
||||
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Compute if a year is a leap year or not.
|
||||
*
|
||||
* @param year The year to test it shall be in the range [70:138]. Year 0 is
|
||||
* translated into year 1900 CE.
|
||||
* @return true if the year in input is a leap year and false otherwise.
|
||||
* @note - For use by the HAL only
|
||||
*/
|
||||
bool _rtc_is_leap_year(int year);
|
||||
|
||||
/* Convert a calendar time into time since UNIX epoch as a time_t.
|
||||
*
|
||||
* This function is a thread safe (partial) replacement for mktime. It is
|
||||
* tailored around RTC peripherals needs and is not by any mean a complete
|
||||
* replacement of mktime.
|
||||
*
|
||||
* @param calendar_time The calendar time to convert into a time_t since epoch.
|
||||
* The fields from tm used for the computation are:
|
||||
* - tm_sec
|
||||
* - tm_min
|
||||
* - tm_hour
|
||||
* - tm_mday
|
||||
* - tm_mon
|
||||
* - tm_year
|
||||
* Other fields are ignored and won't be renormalized by a call to this function.
|
||||
* A valid calendar time is comprised between the 1st january of 1970 at
|
||||
* 00:00:00 and the 19th of january 2038 at 03:14:07.
|
||||
*
|
||||
* @return The calendar time as seconds since UNIX epoch if the input is in the
|
||||
* valid range. Otherwise ((time_t) -1).
|
||||
*
|
||||
* @note Leap seconds are not supported.
|
||||
* @note Values in output range from 0 to INT_MAX.
|
||||
* @note - For use by the HAL only
|
||||
*/
|
||||
time_t _rtc_mktime(const struct tm* calendar_time);
|
||||
|
||||
/* Convert a given time in seconds since epoch into calendar time.
|
||||
*
|
||||
* This function is a thread safe (partial) replacement for localtime. It is
|
||||
* tailored around RTC peripherals specification and is not by any means a
|
||||
* complete of localtime.
|
||||
*
|
||||
* @param timestamp The time (in seconds) to convert into calendar time. Valid
|
||||
* input are in the range [0 : INT32_MAX].
|
||||
* @param calendar_time Pointer to the object which will contain the result of
|
||||
* the conversion. The tm fields filled by this function are:
|
||||
* - tm_sec
|
||||
* - tm_min
|
||||
* - tm_hour
|
||||
* - tm_mday
|
||||
* - tm_mon
|
||||
* - tm_year
|
||||
* - tm_wday
|
||||
* - tm_yday
|
||||
* The object remains untouched if the time in input is invalid.
|
||||
* @return true if the conversion was successful, false otherwise.
|
||||
*
|
||||
* @note - For use by the HAL only
|
||||
*/
|
||||
bool _rtc_localtime(time_t timestamp, struct tm* calendar_time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBED_MKTIME_H */
|
||||
|
||||
/** @}*/
|
|
@ -18,6 +18,7 @@
|
|||
#include "cmsis.h"
|
||||
#include "sysclk.h"
|
||||
#include "rtc.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
static int rtc_inited = 0;
|
||||
|
||||
|
@ -70,7 +71,7 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_year = (ul_year - 1900);
|
||||
|
||||
/* Convert to timestamp */
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -80,19 +81,22 @@ void rtc_write(time_t t)
|
|||
/* Initialize the RTC is not yet initialized */
|
||||
rtc_init();
|
||||
}
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
uint32_t ul_hour, ul_minute, ul_second;
|
||||
uint32_t ul_year, ul_month, ul_day, ul_week;
|
||||
|
||||
ul_second = timeinfo->tm_sec;
|
||||
ul_minute = timeinfo->tm_min;
|
||||
ul_hour = timeinfo->tm_hour;
|
||||
ul_day = timeinfo->tm_mday;
|
||||
ul_week = timeinfo->tm_wday;
|
||||
ul_month = timeinfo->tm_mon;
|
||||
ul_year = timeinfo->tm_year;
|
||||
ul_second = timeinfo.tm_sec;
|
||||
ul_minute = timeinfo.tm_min;
|
||||
ul_hour = timeinfo.tm_hour;
|
||||
ul_day = timeinfo.tm_mday;
|
||||
ul_week = timeinfo.tm_wday;
|
||||
ul_month = timeinfo.tm_mon;
|
||||
ul_year = timeinfo.tm_year;
|
||||
|
||||
/* Set the RTC */
|
||||
rtc_set_time(RTC, ul_hour, ul_minute, ul_second);
|
||||
rtc_set_date(RTC, ul_year, ul_month, ul_day, ul_week);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mbed_error.h"
|
||||
#include "nu_modutil.h"
|
||||
#include "nu_miscutil.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
#define YEAR0 1900
|
||||
//#define EPOCH_YR 1970
|
||||
|
@ -86,7 +87,7 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_sec = rtc_datetime.u32Second;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
@ -98,18 +99,21 @@ void rtc_write(time_t t)
|
|||
}
|
||||
|
||||
// Convert timestamp to struct tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T rtc_datetime;
|
||||
|
||||
// Convert S_RTC_TIME_DATA_T to struct tm
|
||||
rtc_datetime.u32Year = timeinfo->tm_year + YEAR0;
|
||||
rtc_datetime.u32Month = timeinfo->tm_mon + 1;
|
||||
rtc_datetime.u32Day = timeinfo->tm_mday;
|
||||
rtc_datetime.u32DayOfWeek = timeinfo->tm_wday;
|
||||
rtc_datetime.u32Hour = timeinfo->tm_hour;
|
||||
rtc_datetime.u32Minute = timeinfo->tm_min;
|
||||
rtc_datetime.u32Second = timeinfo->tm_sec;
|
||||
rtc_datetime.u32Year = timeinfo.tm_year + YEAR0;
|
||||
rtc_datetime.u32Month = timeinfo.tm_mon + 1;
|
||||
rtc_datetime.u32Day = timeinfo.tm_mday;
|
||||
rtc_datetime.u32DayOfWeek = timeinfo.tm_wday;
|
||||
rtc_datetime.u32Hour = timeinfo.tm_hour;
|
||||
rtc_datetime.u32Minute = timeinfo.tm_min;
|
||||
rtc_datetime.u32Second = timeinfo.tm_sec;
|
||||
rtc_datetime.u32TimeScale = RTC_CLOCK_24;
|
||||
|
||||
// NOTE: Timing issue with write to RTC registers. This delay is empirical, not rational.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mbed_error.h"
|
||||
#include "nu_modutil.h"
|
||||
#include "nu_miscutil.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
#define YEAR0 1900
|
||||
//#define EPOCH_YR 1970
|
||||
|
@ -86,7 +87,7 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_sec = rtc_datetime.u32Second;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
@ -98,18 +99,21 @@ void rtc_write(time_t t)
|
|||
}
|
||||
|
||||
// Convert timestamp to struct tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T rtc_datetime;
|
||||
|
||||
// Convert S_RTC_TIME_DATA_T to struct tm
|
||||
rtc_datetime.u32Year = timeinfo->tm_year + YEAR0;
|
||||
rtc_datetime.u32Month = timeinfo->tm_mon + 1;
|
||||
rtc_datetime.u32Day = timeinfo->tm_mday;
|
||||
rtc_datetime.u32DayOfWeek = timeinfo->tm_wday;
|
||||
rtc_datetime.u32Hour = timeinfo->tm_hour;
|
||||
rtc_datetime.u32Minute = timeinfo->tm_min;
|
||||
rtc_datetime.u32Second = timeinfo->tm_sec;
|
||||
rtc_datetime.u32Year = timeinfo.tm_year + YEAR0;
|
||||
rtc_datetime.u32Month = timeinfo.tm_mon + 1;
|
||||
rtc_datetime.u32Day = timeinfo.tm_mday;
|
||||
rtc_datetime.u32DayOfWeek = timeinfo.tm_wday;
|
||||
rtc_datetime.u32Hour = timeinfo.tm_hour;
|
||||
rtc_datetime.u32Minute = timeinfo.tm_min;
|
||||
rtc_datetime.u32Second = timeinfo.tm_sec;
|
||||
rtc_datetime.u32TimeScale = RTC_CLOCK_24;
|
||||
|
||||
// NOTE: Timing issue with write to RTC registers. This delay is empirical, not rational.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "rtc_api.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
// ensure rtc is running (unchanged if already running)
|
||||
|
||||
|
@ -88,25 +89,28 @@ time_t rtc_read(void) {
|
|||
timeinfo.tm_year = LPC_RTC->YEAR - 1900;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void rtc_write(time_t t) {
|
||||
// Convert the time in to a tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause clock, and clear counter register (clears us count)
|
||||
LPC_RTC->CCR |= 2;
|
||||
|
||||
// Set the RTC
|
||||
LPC_RTC->SEC = timeinfo->tm_sec;
|
||||
LPC_RTC->MIN = timeinfo->tm_min;
|
||||
LPC_RTC->HOUR = timeinfo->tm_hour;
|
||||
LPC_RTC->DOM = timeinfo->tm_mday;
|
||||
LPC_RTC->MONTH = timeinfo->tm_mon + 1;
|
||||
LPC_RTC->YEAR = timeinfo->tm_year + 1900;
|
||||
LPC_RTC->SEC = timeinfo.tm_sec;
|
||||
LPC_RTC->MIN = timeinfo.tm_min;
|
||||
LPC_RTC->HOUR = timeinfo.tm_hour;
|
||||
LPC_RTC->DOM = timeinfo.tm_mday;
|
||||
LPC_RTC->MONTH = timeinfo.tm_mon + 1;
|
||||
LPC_RTC->YEAR = timeinfo.tm_year + 1900;
|
||||
|
||||
// Restart clock
|
||||
LPC_RTC->CCR &= ~((uint32_t)2);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "rtc_api.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
// ensure rtc is running (unchanged if already running)
|
||||
|
||||
|
@ -87,25 +88,28 @@ time_t rtc_read(void) {
|
|||
timeinfo.tm_year = LPC_RTC->YEAR - 1900;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void rtc_write(time_t t) {
|
||||
// Convert the time in to a tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause clock, and clear counter register (clears us count)
|
||||
LPC_RTC->CCR |= 2;
|
||||
|
||||
// Set the RTC
|
||||
LPC_RTC->SEC = timeinfo->tm_sec;
|
||||
LPC_RTC->MIN = timeinfo->tm_min;
|
||||
LPC_RTC->HOUR = timeinfo->tm_hour;
|
||||
LPC_RTC->DOM = timeinfo->tm_mday;
|
||||
LPC_RTC->MONTH = timeinfo->tm_mon + 1;
|
||||
LPC_RTC->YEAR = timeinfo->tm_year + 1900;
|
||||
LPC_RTC->SEC = timeinfo.tm_sec;
|
||||
LPC_RTC->MIN = timeinfo.tm_min;
|
||||
LPC_RTC->HOUR = timeinfo.tm_hour;
|
||||
LPC_RTC->DOM = timeinfo.tm_mday;
|
||||
LPC_RTC->MONTH = timeinfo.tm_mon + 1;
|
||||
LPC_RTC->YEAR = timeinfo.tm_year + 1900;
|
||||
|
||||
// Restart clock
|
||||
LPC_RTC->CCR &= ~((uint32_t)2);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* Ported to NXP LPC43XX by Micromint USA <support@micromint.com>
|
||||
*/
|
||||
#include "rtc_api.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
// ensure rtc is running (unchanged if already running)
|
||||
|
||||
|
@ -101,27 +102,30 @@ time_t rtc_read(void) {
|
|||
timeinfo.tm_year = LPC_RTC->TIME[RTC_TIMETYPE_YEAR] - 1900;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void rtc_write(time_t t) {
|
||||
// Convert the time in to a tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause clock, and clear counter register (clears us count)
|
||||
LPC_RTC->CCR |= 2;
|
||||
|
||||
// Set the RTC
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_SECOND] = timeinfo->tm_sec;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_MINUTE] = timeinfo->tm_min;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_HOUR] = timeinfo->tm_hour;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_DAYOFMONTH] = timeinfo->tm_mday;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_DAYOFWEEK] = timeinfo->tm_wday;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_DAYOFYEAR] = timeinfo->tm_yday;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_MONTH] = timeinfo->tm_mon + 1;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_YEAR] = timeinfo->tm_year + 1900;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_SECOND] = timeinfo.tm_sec;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_MINUTE] = timeinfo.tm_min;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_HOUR] = timeinfo.tm_hour;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_DAYOFMONTH] = timeinfo.tm_mday;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_DAYOFWEEK] = timeinfo.tm_wday;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_DAYOFYEAR] = timeinfo.tm_yday;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_MONTH] = timeinfo.tm_mon + 1;
|
||||
LPC_RTC->TIME[RTC_TIMETYPE_YEAR] = timeinfo.tm_year + 1900;
|
||||
|
||||
// Restart clock
|
||||
LPC_RTC->CCR &= ~((uint32_t)2);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "rtc_api.h"
|
||||
#include "rtc_iodefine.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
|
||||
#define RCR1_VAL_ON (0x08u) // AIE = 1
|
||||
|
@ -213,7 +214,7 @@ time_t rtc_read(void) {
|
|||
|
||||
if (err == 0) {
|
||||
// Convert to timestamp
|
||||
t = mktime(&timeinfo);
|
||||
t = _rtc_mktime(&timeinfo);
|
||||
} else {
|
||||
// Error
|
||||
t = TIME_ERROR_VAL;
|
||||
|
@ -303,7 +304,10 @@ static int rtc_dec16_to_hex(uint16_t dec_val, uint16_t offset, int *hex_val) {
|
|||
*/
|
||||
void rtc_write(time_t t) {
|
||||
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
volatile uint16_t dummy_read;
|
||||
|
||||
if (rtc_isenabled() != 0) {
|
||||
|
@ -314,12 +318,12 @@ void rtc_write(time_t t) {
|
|||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
|
||||
RTC.RSECCNT = rtc_hex8_to_dec(timeinfo->tm_sec);
|
||||
RTC.RMINCNT = rtc_hex8_to_dec(timeinfo->tm_min);
|
||||
RTC.RHRCNT = rtc_hex8_to_dec(timeinfo->tm_hour);
|
||||
RTC.RDAYCNT = rtc_hex8_to_dec(timeinfo->tm_mday);
|
||||
RTC.RMONCNT = rtc_hex8_to_dec(timeinfo->tm_mon + 1);
|
||||
RTC.RYRCNT = rtc_hex16_to_dec(timeinfo->tm_year + 1900);
|
||||
RTC.RSECCNT = rtc_hex8_to_dec(timeinfo.tm_sec);
|
||||
RTC.RMINCNT = rtc_hex8_to_dec(timeinfo.tm_min);
|
||||
RTC.RHRCNT = rtc_hex8_to_dec(timeinfo.tm_hour);
|
||||
RTC.RDAYCNT = rtc_hex8_to_dec(timeinfo.tm_mday);
|
||||
RTC.RMONCNT = rtc_hex8_to_dec(timeinfo.tm_mon + 1);
|
||||
RTC.RYRCNT = rtc_hex16_to_dec(timeinfo.tm_year + 1900);
|
||||
dummy_read = (uint16_t)RTC.RYRCNT;
|
||||
dummy_read = (uint16_t)RTC.RYRCNT;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "rtc_api.h"
|
||||
#include "rtc_iodefine.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
|
||||
#define RCR1_VAL_ON (0x08u) // AIE = 1
|
||||
|
@ -247,7 +248,7 @@ time_t rtc_read(void) {
|
|||
|
||||
if (err == 0) {
|
||||
// Convert to timestamp
|
||||
t = mktime(&timeinfo);
|
||||
t = _rtc_mktime(&timeinfo);
|
||||
} else {
|
||||
// Error
|
||||
t = TIME_ERROR_VAL;
|
||||
|
@ -337,7 +338,10 @@ static int rtc_dec16_to_hex(uint16_t dec_val, uint16_t offset, int *hex_val) {
|
|||
*/
|
||||
void rtc_write(time_t t) {
|
||||
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
volatile uint16_t dummy_read;
|
||||
|
||||
if (rtc_isenabled() != 0) {
|
||||
|
@ -348,12 +352,12 @@ void rtc_write(time_t t) {
|
|||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
dummy_read = (uint16_t)RTC.RCR2;
|
||||
|
||||
RTC.RSECCNT = rtc_hex8_to_dec(timeinfo->tm_sec);
|
||||
RTC.RMINCNT = rtc_hex8_to_dec(timeinfo->tm_min);
|
||||
RTC.RHRCNT = rtc_hex8_to_dec(timeinfo->tm_hour);
|
||||
RTC.RDAYCNT = rtc_hex8_to_dec(timeinfo->tm_mday);
|
||||
RTC.RMONCNT = rtc_hex8_to_dec(timeinfo->tm_mon + 1);
|
||||
RTC.RYRCNT = rtc_hex16_to_dec(timeinfo->tm_year + 1900);
|
||||
RTC.RSECCNT = rtc_hex8_to_dec(timeinfo.tm_sec);
|
||||
RTC.RMINCNT = rtc_hex8_to_dec(timeinfo.tm_min);
|
||||
RTC.RHRCNT = rtc_hex8_to_dec(timeinfo.tm_hour);
|
||||
RTC.RDAYCNT = rtc_hex8_to_dec(timeinfo.tm_mday);
|
||||
RTC.RMONCNT = rtc_hex8_to_dec(timeinfo.tm_mon + 1);
|
||||
RTC.RYRCNT = rtc_hex16_to_dec(timeinfo.tm_year + 1900);
|
||||
dummy_read = (uint16_t)RTC.RYRCNT;
|
||||
dummy_read = (uint16_t)RTC.RYRCNT;
|
||||
|
||||
|
|
|
@ -19,54 +19,17 @@
|
|||
#if DEVICE_RTC
|
||||
#include <time.h>
|
||||
#include "timer_api.h" // software-RTC: use a g-timer for the tick of the RTC
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
#define SW_RTC_TIMER_ID TIMER4
|
||||
|
||||
static gtimer_t sw_rtc;
|
||||
static struct tm rtc_timeinfo;
|
||||
static int sw_rtc_en=0;
|
||||
|
||||
static const u8 dim[14] = {
|
||||
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28 };
|
||||
|
||||
static inline bool is_leap_year(unsigned int year)
|
||||
{
|
||||
return (!(year % 4) && (year % 100)) || !(year % 400);
|
||||
}
|
||||
|
||||
|
||||
static u8 days_in_month (u8 month, u8 year)
|
||||
{
|
||||
u8 ret = dim [ month - 1 ];
|
||||
if (ret == 0)
|
||||
ret = is_leap_year (year) ? 29 : 28;
|
||||
return ret;
|
||||
}
|
||||
static time_t rtc_time;
|
||||
|
||||
void sw_rtc_tick_handler(uint32_t id)
|
||||
{
|
||||
if(++rtc_timeinfo.tm_sec > 59) { // Increment seconds, check for overflow
|
||||
rtc_timeinfo.tm_sec = 0; // Reset seconds
|
||||
if(++rtc_timeinfo.tm_min > 59) { // Increment minutes, check for overflow
|
||||
rtc_timeinfo.tm_min = 0; // Reset minutes
|
||||
if(++rtc_timeinfo.tm_hour > 23) { // Increment hours, check for overflow
|
||||
rtc_timeinfo.tm_hour = 0; // Reset hours
|
||||
++rtc_timeinfo.tm_yday; // Increment day of year
|
||||
if(++rtc_timeinfo.tm_wday > 6) // Increment day of week, check for overflow
|
||||
rtc_timeinfo.tm_wday = 0; // Reset day of week
|
||||
// Increment day of month, check for overflow
|
||||
if(++rtc_timeinfo.tm_mday >
|
||||
days_in_month(rtc_timeinfo.tm_mon, rtc_timeinfo.tm_year + 1900)) {
|
||||
rtc_timeinfo.tm_mday = 1; // Reset day of month
|
||||
if(++rtc_timeinfo.tm_mon > 11) { // Increment month, check for overflow
|
||||
rtc_timeinfo.tm_mon = 0; // Reset month
|
||||
rtc_timeinfo.tm_yday = 0; // Reset day of year
|
||||
++rtc_timeinfo.tm_year; // Increment year
|
||||
} // - year
|
||||
} // - month
|
||||
} // - day
|
||||
} // - hour
|
||||
}
|
||||
rtc_time++;
|
||||
}
|
||||
|
||||
void rtc_init(void)
|
||||
|
@ -92,35 +55,15 @@ int rtc_isenabled(void)
|
|||
|
||||
time_t rtc_read(void)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
// Convert to timestamp
|
||||
t = mktime(&rtc_timeinfo);
|
||||
|
||||
return t;
|
||||
return rtc_time;
|
||||
}
|
||||
|
||||
void rtc_write(time_t t)
|
||||
{
|
||||
// Convert the time in to a tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
|
||||
if (timeinfo == NULL) {
|
||||
// Error
|
||||
return;
|
||||
}
|
||||
|
||||
gtimer_stop(&sw_rtc);
|
||||
|
||||
// Set the RTC
|
||||
rtc_timeinfo.tm_sec = timeinfo->tm_sec;
|
||||
rtc_timeinfo.tm_min = timeinfo->tm_min;
|
||||
rtc_timeinfo.tm_hour = timeinfo->tm_hour;
|
||||
rtc_timeinfo.tm_mday = timeinfo->tm_mday;
|
||||
rtc_timeinfo.tm_wday = timeinfo->tm_wday;
|
||||
rtc_timeinfo.tm_yday = timeinfo->tm_yday;
|
||||
rtc_timeinfo.tm_mon = timeinfo->tm_mon;
|
||||
rtc_timeinfo.tm_year = timeinfo->tm_year;
|
||||
rtc_time = t;
|
||||
|
||||
gtimer_start(&sw_rtc);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "rtc_api.h"
|
||||
#include "rtc_api_hal.h"
|
||||
#include "mbed_error.h"
|
||||
#include "mbed_mktime.h"
|
||||
|
||||
static RTC_HandleTypeDef RtcHandle;
|
||||
|
||||
|
@ -239,7 +240,7 @@ time_t rtc_read(void)
|
|||
timeinfo.tm_isdst = -1;
|
||||
|
||||
// Convert to timestamp
|
||||
time_t t = mktime(&timeinfo);
|
||||
time_t t = _rtc_mktime(&timeinfo);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
@ -252,20 +253,23 @@ void rtc_write(time_t t)
|
|||
RtcHandle.Instance = RTC;
|
||||
|
||||
// Convert the time into a tm
|
||||
struct tm *timeinfo = localtime(&t);
|
||||
struct tm timeinfo;
|
||||
if (_rtc_localtime(t, &timeinfo) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill RTC structures
|
||||
if (timeinfo->tm_wday == 0) {
|
||||
if (timeinfo.tm_wday == 0) {
|
||||
dateStruct.WeekDay = 7;
|
||||
} else {
|
||||
dateStruct.WeekDay = timeinfo->tm_wday;
|
||||
dateStruct.WeekDay = timeinfo.tm_wday;
|
||||
}
|
||||
dateStruct.Month = timeinfo->tm_mon + 1;
|
||||
dateStruct.Date = timeinfo->tm_mday;
|
||||
dateStruct.Year = timeinfo->tm_year - 68;
|
||||
timeStruct.Hours = timeinfo->tm_hour;
|
||||
timeStruct.Minutes = timeinfo->tm_min;
|
||||
timeStruct.Seconds = timeinfo->tm_sec;
|
||||
dateStruct.Month = timeinfo.tm_mon + 1;
|
||||
dateStruct.Date = timeinfo.tm_mday;
|
||||
dateStruct.Year = timeinfo.tm_year - 68;
|
||||
timeStruct.Hours = timeinfo.tm_hour;
|
||||
timeStruct.Minutes = timeinfo.tm_min;
|
||||
timeStruct.Seconds = timeinfo.tm_sec;
|
||||
|
||||
#if !(TARGET_STM32F1)
|
||||
timeStruct.TimeFormat = RTC_HOURFORMAT_24;
|
||||
|
|
Loading…
Reference in New Issue