BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
rtc_calc_auto.py
00001 """ 00002 mbed SDK 00003 Copyright (c) 2011-2013 ARM Limited 00004 00005 Licensed under the Apache License, Version 2.0 (the "License"); 00006 you may not use this file except in compliance with the License. 00007 You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software 00012 distributed under the License is distributed on an "AS IS" BASIS, 00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 See the License for the specific language governing permissions and 00015 limitations under the License. 00016 """ 00017 00018 from mbed_host_tests import BaseHostTest 00019 import time 00020 import calendar 00021 import datetime 00022 00023 class RTC_time_calc_test (BaseHostTest): 00024 """ 00025 This is the host part of the test to verify if: 00026 - _rtc_mktime function converts a calendar time into time since UNIX epoch as a time_t, 00027 - _rtc_localtime function converts a given time in seconds since epoch into calendar time. 00028 00029 The same algoritm to generate next calendar time to be tested is used by both parts of the test. 00030 We will check if correct time since UNIX epoch is calculated for the first and the last day 00031 of each month and across valid years. 00032 00033 Mbed part of the test sends calculated time since UNIX epoch. 00034 This part validates given value and responds to indicate pass or fail. 00035 Additionally it sends also encoded day of week and day of year which 00036 will be needed to verify _rtc_localtime. 00037 00038 Support for both types of RTC devices is provided: 00039 - RTCs which handles all leap years in the mentioned year range correctly. Leap year is determined by checking if 00040 the year counter value is divisible by 400, 100, and 4. No problem here. 00041 - RTCs which handles leap years correctly up to 2100. The RTC does a simple bit comparison to see if the two 00042 lowest order bits of the year counter are zero. In this case 2100 year will be considered 00043 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 00044 29.02.2100 (invalid). So after 28.02.2100 the day counter will be off by a day. 00045 00046 """ 00047 00048 edge_date = datetime.datetime(2100, 2, 28, 0, 0, 0) 00049 00050 # Test the following years: 00051 # - first - 1970 00052 # - example not leap year (not divisible by 4) 00053 # - example leap year (divisible by 4 and by 100 and by 400) 00054 # - example leap year (divisible by 4 and not by 100) 00055 # - example not leap year (divisible by 4 and by 100) 00056 # - last fully supported - 2105 00057 years = [1970, 1971, 2000, 2096, 2100, 2105] 00058 year_id = 0 00059 00060 00061 00062 full_leap_year_support = False 00063 00064 RTC_FULL_LEAP_YEAR_SUPPORT = 0 00065 RTC_PARTIAL_LEAP_YEAR_SUPPORT = 1 00066 00067 def _set_leap_year_support(self, key, value, timestamp): 00068 if (int(value) == self.RTC_FULL_LEAP_YEAR_SUPPORT ): 00069 self.full_leap_year_support = True 00070 else: 00071 self.full_leap_year_support = False 00072 00073 self.first = True 00074 self.date = datetime.datetime(1970, 1, 1, 23, 0, 0) 00075 self.year_id = 0 00076 00077 def _verify_timestamp(self, key, value, timestamp): 00078 # week day in python is counted from sunday(0) and on mbed side week day is counted from monday(0). 00079 # year day in python is counted from 1 and on mbed side year day is counted from 0. 00080 week_day = ((self.date .timetuple().tm_wday + 1) % 7) 00081 year_day = self.date .timetuple().tm_yday - 1 00082 00083 # Fix for RTC which not have full leap year support. 00084 if (not self.full_leap_year_support ): 00085 if self.date >= self.edge_date : 00086 # After 28.02.2100 we should be one day off - add this day and store original 00087 date_org = self.date 00088 self.date += datetime.timedelta(days = 1) 00089 00090 # Adjust week day. 00091 week_day = ((self.date .timetuple().tm_wday + 1) % 7) 00092 00093 # Adjust year day. 00094 if (self.date .year == 2100): 00095 year_day = self.date .timetuple().tm_yday - 1 00096 else: 00097 year_day = date_org.timetuple().tm_yday - 1 00098 00099 # Last day in year 00100 if (self.date .month == 1 and self.date .day == 1): 00101 if (self.date .year == 2101): 00102 # Exception for year 2100 - ivalid handled by RTC without full leap year support 00103 year_day = 365 00104 else: 00105 year_day = date_org.timetuple().tm_yday - 1 00106 00107 t = (self.date .year , self.date .month, self.date .day, self.date .hour, self.date .minute, self.date .second, 0, 0, 0) 00108 00109 expected_timestamp = calendar.timegm(t) 00110 actual_timestamp = int(value) & 0xffffffff # convert to unsigned int 00111 00112 # encode week day and year day in the response 00113 response = (week_day << 16) | year_day 00114 00115 if (actual_timestamp == expected_timestamp): 00116 # response contains encoded week day and year day 00117 self.send_kv("passed", str(response)) 00118 else: 00119 self.send_kv("failed", 0) 00120 print "expected = %d, result = %d" % (expected_timestamp , actual_timestamp) 00121 00122 # calculate next date 00123 if (self.first ): 00124 days_range = calendar.monthrange(self.date .year, self.date .month) 00125 self.date = self.date .replace(day = days_range[1], minute = 59, second = 59) 00126 self.first = not self.first 00127 else: 00128 self.date += datetime.timedelta(days = 1) 00129 if (self.date .month == 1): 00130 self.year_id += 1 00131 if (len(self.years ) == self.year_id ): 00132 # All years were processed, no need to calc next date 00133 return 00134 self.date = self.date .replace(year = self.years [self.year_id ]) 00135 self.date = self.date .replace(day = 1, minute = 0, second = 0) 00136 self.first = not self.first 00137 00138 def setup(self): 00139 self.register_callback('timestamp', self._verify_timestamp ) 00140 self.register_callback('leap_year_setup', self._set_leap_year_support )
Generated on Tue Jul 12 2022 12:22:19 by
