Skip to content

Commit fcdaecc

Browse files
committed
Add tests for extended RTC.
1 parent dc5a66d commit fcdaecc

File tree

3 files changed

+493
-188
lines changed

3 files changed

+493
-188
lines changed

TESTS/host_tests/rtc_calc_auto.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
"""
2+
mbed SDK
3+
Copyright (c) 2011-2013 ARM Limited
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
"""
17+
18+
from mbed_host_tests import BaseHostTest
19+
import time
20+
import calendar
21+
import datetime
22+
23+
class RTC_time_calc_test(BaseHostTest):
24+
"""
25+
This is the host part of the test to verify if:
26+
- _rtc_mktime function converts a calendar time into time since UNIX epoch as a time_t,
27+
- _rtc_localtime function converts a given time in seconds since epoch into calendar time.
28+
29+
The same algoritm to generate next calendar time to be tested is used by both parts of the test.
30+
We will check if correct time since UNIX epoch is calculated for the first and the last day
31+
of each month and across valid years.
32+
33+
Mbed part of the test sends calculated time since UNIX epoch.
34+
This part validates given value and responds to indicate pass or fail.
35+
Additionally it sends also encoded day of week and day of year which
36+
will be needed to verify _rtc_localtime.
37+
38+
Support for both types of RTC devices is provided:
39+
- RTCs which handles all leap years in the mentioned year range correctly. Leap year is determined by checking if
40+
the year counter value is divisible by 400, 100, and 4. No problem here.
41+
- RTCs which handles leap years correctly up to 2100. The RTC does a simple bit comparison to see if the two
42+
lowest order bits of the year counter are zero. In this case 2100 year will be considered
43+
incorrectly as a leap year, so the last valid point in time will be 28.02.2100 23:59:59 and next day will be
44+
29.02.2100 (invalid). So after 28.02.2100 the day counter will be off by a day.
45+
46+
"""
47+
48+
edge_date = datetime.datetime(2100, 2, 28, 0, 0, 0)
49+
50+
years = [1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980,
51+
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
52+
2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106]
53+
year_id = 0
54+
55+
56+
57+
full_leap_year_support = False
58+
59+
RTC_FULL_LEAP_YEAR_SUPPORT = 0
60+
RTC_PARTIAL_LEAP_YEAR_SUPPORT = 1
61+
62+
def _set_leap_year_support(self, key, value, timestamp):
63+
if (int(value) == self.RTC_FULL_LEAP_YEAR_SUPPORT):
64+
self.full_leap_year_support = True
65+
else:
66+
self.full_leap_year_support = False
67+
68+
self.first = True
69+
self.date = datetime.datetime(1970, 1, 1, 23, 0, 0)
70+
self.year_id = 0
71+
72+
def _verify_timestamp(self, key, value, timestamp):
73+
# week day in python is counted from sunday(0) and on mbed side week day is counted from monday(0).
74+
# year day in python is counted from 1 and on mbed side year day is counted from 0.
75+
week_day = ((self.date.timetuple().tm_wday + 1) % 7)
76+
year_day = self.date.timetuple().tm_yday - 1
77+
78+
# Fix for RTC which not have full leap year support.
79+
if (not self.full_leap_year_support):
80+
if self.date >= self.edge_date:
81+
# After 28.02.2100 we should be one day off - add this day and store original
82+
date_org = self.date
83+
self.date += datetime.timedelta(days = 1)
84+
85+
# Adjust week day.
86+
week_day = ((self.date.timetuple().tm_wday + 1) % 7)
87+
88+
# Adjust year day.
89+
if (self.date.year == 2100):
90+
year_day = self.date.timetuple().tm_yday - 1
91+
else:
92+
year_day = date_org.timetuple().tm_yday - 1
93+
94+
# Last day in year
95+
if (self.date.month == 1 and self.date.day == 1):
96+
if (self.date.year == 2101):
97+
# Exception for year 2100 - ivalid handled by RTC without full leap year support
98+
year_day = 365
99+
else:
100+
year_day = date_org.timetuple().tm_yday - 1
101+
102+
t = (self.date.year , self.date.month, self.date.day, self.date.hour, self.date.minute, self.date.second, 0, 0, 0)
103+
104+
expected_timestamp = calendar.timegm(t)
105+
actual_timestamp = int(value) & 0xffffffff # convert to unsigned int
106+
107+
# encode week day and year day in the response
108+
response = (week_day << 16) | year_day
109+
110+
if (actual_timestamp == expected_timestamp):
111+
# response contains encoded week day and year day
112+
self.send_kv("passed", str(response))
113+
else:
114+
self.send_kv("failed", 0)
115+
print "expected = %d, result = %d" % (expected_timestamp , actual_timestamp)
116+
117+
# calculate next date
118+
if (self.first):
119+
days_range = calendar.monthrange(self.date.year, self.date.month)
120+
self.date = self.date.replace(day = days_range[1], minute = 59, second = 59)
121+
self.first = not self.first
122+
else:
123+
self.date += datetime.timedelta(days = 1)
124+
if (self.date.month == 1):
125+
self.year_id += 1
126+
self.date = self.date.replace(year = self.years[self.year_id])
127+
self.date = self.date.replace(day = 1, minute = 0, second = 0)
128+
self.first = not self.first
129+
130+
def setup(self):
131+
self.register_callback('timestamp', self._verify_timestamp)
132+
self.register_callback('leap_year_setup', self._set_leap_year_support)
133+
134+
def result(self):
135+
return self.__result
136+
137+
def teardown(self):
138+
pass

0 commit comments

Comments
 (0)