3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 RTC Architectural Protocol GUID as defined in EFI 2.0
21 #include "RealTimeClock.h"
45 INTN mDayOfMonth
[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
55 TODO: Add function description
59 Address - TODO: add argument description
63 TODO: add return values
67 IoWrite8 (PCAT_RTC_ADDRESS_REGISTER
, (UINT8
) (Address
| (UINT8
) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER
) & 0x80)));
68 return IoRead8 (PCAT_RTC_DATA_REGISTER
);
80 Compare the Hour, Minute and Second of the 'From' time and the 'To' time.
81 Only compare H/M/S in EFI_TIME and ignore other fields here.
90 >0 : The H/M/S of the 'From' time is later than those of 'To' time
91 ==0 : The H/M/S of the 'From' time is same as those of 'To' time
92 <0 : The H/M/S of the 'From' time is earlier than those of 'To' time
97 if ((From
->Hour
> To
->Hour
) ||
98 ((From
->Hour
== To
->Hour
) && (From
->Minute
> To
->Minute
)) ||
99 ((From
->Hour
== To
->Hour
) && (From
->Minute
== To
->Minute
) && (From
->Second
> To
->Second
))) {
101 } else if ((From
->Hour
== To
->Hour
) && (From
->Minute
== To
->Minute
) && (From
->Second
== To
->Second
)) {
117 TODO: Add function description
121 Address - TODO: add argument description
122 Data - TODO: add argument description
126 TODO: add return values
130 IoWrite8 (PCAT_RTC_ADDRESS_REGISTER
, (UINT8
) (Address
| (UINT8
) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER
) & 0x80)));
131 IoWrite8 (PCAT_RTC_DATA_REGISTER
, Data
);
136 IN PC_RTC_MODULE_GLOBALS
*Global
142 TODO: Add function description
146 Global - TODO: add argument description
150 EFI_DEVICE_ERROR - TODO: Add description for return value
151 EFI_SUCCESS - TODO: Add description for return value
156 RTC_REGISTER_A RegisterA
;
157 RTC_REGISTER_B RegisterB
;
158 //RTC_REGISTER_C RegisterC;
159 RTC_REGISTER_D RegisterD
;
164 // Acquire RTC Lock to make access to RTC atomic
166 EfiAcquireLock (&Global
->RtcLock
);
169 // Initialize RTC Register
171 // Make sure Division Chain is properly configured,
172 // or RTC clock won't "tick" -- time won't increment
174 RegisterA
.Data
= RTC_INIT_REGISTER_A
;
175 RtcWrite (RTC_ADDRESS_REGISTER_A
, RegisterA
.Data
);
180 RegisterB
.Data
= RtcRead (RTC_ADDRESS_REGISTER_B
);
183 // Clear RTC flag register
185 //RegisterC.Data = RtcRead (RTC_ADDRESS_REGISTER_C);
188 // Clear RTC register D
190 RegisterD
.Data
= RTC_INIT_REGISTER_D
;
191 RtcWrite (RTC_ADDRESS_REGISTER_D
, RegisterD
.Data
);
194 // Wait for up to 0.1 seconds for the RTC to be updated
196 // KEN: BUGBUG following wait action will cause failure under vmware environment.
198 //Status = RtcWaitToUpdate (100000);
199 //if (EFI_ERROR (Status)) {
200 // EfiReleaseLock (&Global->RtcLock);
201 // return EFI_DEVICE_ERROR;
204 // Get the Time/Date/Daylight Savings values.
206 Time
.Second
= RtcRead (RTC_ADDRESS_SECONDS
);
207 Time
.Minute
= RtcRead (RTC_ADDRESS_MINUTES
);
208 Time
.Hour
= RtcRead (RTC_ADDRESS_HOURS
);
209 Time
.Day
= RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH
);
210 Time
.Month
= RtcRead (RTC_ADDRESS_MONTH
);
211 Time
.Year
= RtcRead (RTC_ADDRESS_YEAR
);
213 ConvertRtcTimeToEfiTime (&Time
, RegisterB
);
215 if (RtcTestCenturyRegister () == EFI_SUCCESS
) {
216 Century
= BcdToDecimal ((UINT8
) (RtcRead (RTC_ADDRESS_CENTURY
) & 0x7f));
218 Century
= BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY
));
221 Time
.Year
= (UINT16
) (Century
* 100 + Time
.Year
);
224 // Set RTC configuration after get original time
226 RtcWrite (RTC_ADDRESS_REGISTER_B
, RTC_INIT_REGISTER_B
);
231 EfiReleaseLock (&Global
->RtcLock
);
234 // Validate time fields
236 Status
= RtcTimeFieldsValid (&Time
);
237 if (EFI_ERROR (Status
)) {
238 Time
.Second
= RTC_INIT_SECOND
;
239 Time
.Minute
= RTC_INIT_MINUTE
;
240 Time
.Hour
= RTC_INIT_HOUR
;
241 Time
.Day
= RTC_INIT_DAY
;
242 Time
.Month
= RTC_INIT_MONTH
;
243 Time
.Year
= RTC_INIT_YEAR
;
246 // Reset time value according to new RTC configuration
248 PcRtcSetTime (&Time
, Global
);
256 IN EFI_TIME_CAPABILITIES
*Capabilities
,
257 IN PC_RTC_MODULE_GLOBALS
*Global
267 // TODO: Time - add argument and description to function comment
268 // TODO: Capabilities - add argument and description to function comment
269 // TODO: Global - add argument and description to function comment
270 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
271 // TODO: EFI_DEVICE_ERROR - add return value to function comment
272 // TODO: EFI_SUCCESS - add return value to function comment
275 RTC_REGISTER_B RegisterB
;
280 // Check parameters for null pointer
283 return EFI_INVALID_PARAMETER
;
287 // Acquire RTC Lock to make access to RTC atomic
289 EfiAcquireLock (&Global
->RtcLock
);
292 // Wait for up to 0.1 seconds for the RTC to be updated
294 Status
= RtcWaitToUpdate (100000);
295 if (EFI_ERROR (Status
)) {
296 EfiReleaseLock (&Global
->RtcLock
);
302 RegisterB
.Data
= RtcRead (RTC_ADDRESS_REGISTER_B
);
305 // Get the Time/Date/Daylight Savings values.
307 Time
->Second
= RtcRead (RTC_ADDRESS_SECONDS
);
308 Time
->Minute
= RtcRead (RTC_ADDRESS_MINUTES
);
309 Time
->Hour
= RtcRead (RTC_ADDRESS_HOURS
);
310 Time
->Day
= RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH
);
311 Time
->Month
= RtcRead (RTC_ADDRESS_MONTH
);
312 Time
->Year
= RtcRead (RTC_ADDRESS_YEAR
);
314 ConvertRtcTimeToEfiTime (Time
, RegisterB
);
316 if (RtcTestCenturyRegister () == EFI_SUCCESS
) {
317 Century
= BcdToDecimal ((UINT8
) (RtcRead (RTC_ADDRESS_CENTURY
) & 0x7f));
319 Century
= BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY
));
322 Time
->Year
= (UINT16
) (Century
* 100 + Time
->Year
);
327 EfiReleaseLock (&Global
->RtcLock
);
330 // Get the variable that containts the TimeZone and Daylight fields
332 Time
->TimeZone
= Global
->SavedTimeZone
;
333 Time
->Daylight
= Global
->Daylight
;
335 //BufferSize = sizeof (INT16) + sizeof (UINT8);
338 // Make sure all field values are in correct range
340 Status
= RtcTimeFieldsValid (Time
);
341 if (EFI_ERROR (Status
)) {
342 return EFI_DEVICE_ERROR
;
345 // Fill in Capabilities if it was passed in
348 Capabilities
->Resolution
= 1;
352 Capabilities
->Accuracy
= 50000000;
356 Capabilities
->SetsToZero
= FALSE
;
365 IN PC_RTC_MODULE_GLOBALS
*Global
375 // TODO: Time - add argument and description to function comment
376 // TODO: Global - add argument and description to function comment
377 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
381 RTC_REGISTER_B RegisterB
;
385 return EFI_INVALID_PARAMETER
;
388 // Make sure that the time fields are valid
390 Status
= RtcTimeFieldsValid (Time
);
391 if (EFI_ERROR (Status
)) {
395 CopyMem (&RtcTime
, Time
, sizeof (EFI_TIME
));
398 // Acquire RTC Lock to make access to RTC atomic
400 EfiAcquireLock (&Global
->RtcLock
);
403 // Wait for up to 0.1 seconds for the RTC to be updated
405 Status
= RtcWaitToUpdate (100000);
406 if (EFI_ERROR (Status
)) {
407 EfiReleaseLock (&Global
->RtcLock
);
411 // Read Register B, and inhibit updates of the RTC
413 RegisterB
.Data
= RtcRead (RTC_ADDRESS_REGISTER_B
);
414 RegisterB
.Bits
.SET
= 1;
415 RtcWrite (RTC_ADDRESS_REGISTER_B
, RegisterB
.Data
);
417 ConvertEfiTimeToRtcTime (&RtcTime
, RegisterB
, &Century
);
419 RtcWrite (RTC_ADDRESS_SECONDS
, RtcTime
.Second
);
420 RtcWrite (RTC_ADDRESS_MINUTES
, RtcTime
.Minute
);
421 RtcWrite (RTC_ADDRESS_HOURS
, RtcTime
.Hour
);
422 RtcWrite (RTC_ADDRESS_DAY_OF_THE_MONTH
, RtcTime
.Day
);
423 RtcWrite (RTC_ADDRESS_MONTH
, RtcTime
.Month
);
424 RtcWrite (RTC_ADDRESS_YEAR
, (UINT8
) RtcTime
.Year
);
425 if (RtcTestCenturyRegister () == EFI_SUCCESS
) {
426 Century
= (UINT8
) ((Century
& 0x7f) | (RtcRead (RTC_ADDRESS_CENTURY
) & 0x80));
429 RtcWrite (RTC_ADDRESS_CENTURY
, Century
);
432 // Allow updates of the RTC registers
434 RegisterB
.Bits
.SET
= 0;
435 RtcWrite (RTC_ADDRESS_REGISTER_B
, RegisterB
.Data
);
440 EfiReleaseLock (&Global
->RtcLock
);
443 // Set the variable that containts the TimeZone and Daylight fields
445 Global
->SavedTimeZone
= Time
->TimeZone
;
446 Global
->Daylight
= Time
->Daylight
;
453 OUT BOOLEAN
*Enabled
,
454 OUT BOOLEAN
*Pending
,
456 IN PC_RTC_MODULE_GLOBALS
*Global
468 // TODO: Enabled - add argument and description to function comment
469 // TODO: Pending - add argument and description to function comment
470 // TODO: Time - add argument and description to function comment
471 // TODO: Global - add argument and description to function comment
472 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
473 // TODO: EFI_DEVICE_ERROR - add return value to function comment
474 // TODO: EFI_DEVICE_ERROR - add return value to function comment
475 // TODO: EFI_SUCCESS - add return value to function comment
478 RTC_REGISTER_B RegisterB
;
479 RTC_REGISTER_C RegisterC
;
483 // Check paramters for null pointers
485 if ((Enabled
== NULL
) || (Pending
== NULL
) || (Time
== NULL
)) {
486 return EFI_INVALID_PARAMETER
;
490 // Acquire RTC Lock to make access to RTC atomic
492 EfiAcquireLock (&Global
->RtcLock
);
495 // Wait for up to 0.1 seconds for the RTC to be updated
497 Status
= RtcWaitToUpdate (100000);
498 if (EFI_ERROR (Status
)) {
499 EfiReleaseLock (&Global
->RtcLock
);
500 return EFI_DEVICE_ERROR
;
503 // Read Register B and Register C
505 RegisterB
.Data
= RtcRead (RTC_ADDRESS_REGISTER_B
);
506 RegisterC
.Data
= RtcRead (RTC_ADDRESS_REGISTER_C
);
509 // Get the Time/Date/Daylight Savings values.
511 *Enabled
= RegisterB
.Bits
.AIE
;
513 Time
->Second
= RtcRead (RTC_ADDRESS_SECONDS_ALARM
);
514 Time
->Minute
= RtcRead (RTC_ADDRESS_MINUTES_ALARM
);
515 Time
->Hour
= RtcRead (RTC_ADDRESS_HOURS_ALARM
);
516 Time
->Day
= RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH
);
517 Time
->Month
= RtcRead (RTC_ADDRESS_MONTH
);
518 Time
->Year
= RtcRead (RTC_ADDRESS_YEAR
);
523 Time
->Day
= RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH
);
524 Time
->Month
= RtcRead (RTC_ADDRESS_MONTH
);
525 Time
->Year
= RtcRead (RTC_ADDRESS_YEAR
);
528 ConvertRtcTimeToEfiTime (Time
, RegisterB
);
530 if (RtcTestCenturyRegister () == EFI_SUCCESS
) {
531 Century
= BcdToDecimal ((UINT8
) (RtcRead (RTC_ADDRESS_CENTURY
) & 0x7f));
533 Century
= BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY
));
536 Time
->Year
= (UINT16
) (Century
* 100 + Time
->Year
);
541 EfiReleaseLock (&Global
->RtcLock
);
544 // Make sure all field values are in correct range
546 Status
= RtcTimeFieldsValid (Time
);
547 if (EFI_ERROR (Status
)) {
548 return EFI_DEVICE_ERROR
;
551 *Pending
= RegisterC
.Bits
.AF
;
561 IN PC_RTC_MODULE_GLOBALS
*Global
573 // TODO: Enable - add argument and description to function comment
574 // TODO: Time - add argument and description to function comment
575 // TODO: Global - add argument and description to function comment
576 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
577 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
578 // TODO: EFI_UNSUPPORTED - add return value to function comment
579 // TODO: EFI_DEVICE_ERROR - add return value to function comment
580 // TODO: EFI_SUCCESS - add return value to function comment
584 RTC_REGISTER_B RegisterB
;
586 EFI_TIME_CAPABILITIES Capabilities
;
591 return EFI_INVALID_PARAMETER
;
594 // Make sure that the time fields are valid
596 Status
= RtcTimeFieldsValid (Time
);
597 if (EFI_ERROR (Status
)) {
598 return EFI_INVALID_PARAMETER
;
601 // Just support set alarm time within 24 hours
603 PcRtcGetTime (&RtcTime
, &Capabilities
, Global
);
604 if (!IsWithinOneDay (&RtcTime
, Time
)) {
605 return EFI_UNSUPPORTED
;
608 // Make a local copy of the time and date
610 CopyMem (&RtcTime
, Time
, sizeof (EFI_TIME
));
614 // Acquire RTC Lock to make access to RTC atomic
616 EfiAcquireLock (&Global
->RtcLock
);
619 // Wait for up to 0.1 seconds for the RTC to be updated
621 Status
= RtcWaitToUpdate (100000);
622 if (EFI_ERROR (Status
)) {
623 EfiReleaseLock (&Global
->RtcLock
);
624 return EFI_DEVICE_ERROR
;
627 // Read Register B, and inhibit updates of the RTC
629 RegisterB
.Data
= RtcRead (RTC_ADDRESS_REGISTER_B
);
631 RegisterB
.Bits
.SET
= 1;
632 RtcWrite (RTC_ADDRESS_REGISTER_B
, RegisterB
.Data
);
635 ConvertEfiTimeToRtcTime (&RtcTime
, RegisterB
, &Century
);
638 // Set RTC alarm time
640 RtcWrite (RTC_ADDRESS_SECONDS_ALARM
, RtcTime
.Second
);
641 RtcWrite (RTC_ADDRESS_MINUTES_ALARM
, RtcTime
.Minute
);
642 RtcWrite (RTC_ADDRESS_HOURS_ALARM
, RtcTime
.Hour
);
644 RegisterB
.Bits
.AIE
= 1;
647 RegisterB
.Bits
.AIE
= 0;
650 // Allow updates of the RTC registers
652 RegisterB
.Bits
.SET
= 0;
653 RtcWrite (RTC_ADDRESS_REGISTER_B
, RegisterB
.Data
);
658 EfiReleaseLock (&Global
->RtcLock
);
677 // TODO: BcdValue - add argument and description to function comment
682 High
= BcdValue
>> 4;
683 Low
= BcdValue
- (High
<< 4);
685 return (UINT8
) (Low
+ (High
* 10));
689 RtcTestCenturyRegister (
702 // TODO: EFI_SUCCESS - add return value to function comment
703 // TODO: EFI_DEVICE_ERROR - add return value to function comment
708 Century
= RtcRead (RTC_ADDRESS_CENTURY
);
710 // RtcWrite (RTC_ADDRESS_CENTURY, 0x00);
712 Temp
= (UINT8
) (RtcRead (RTC_ADDRESS_CENTURY
) & 0x7f);
713 RtcWrite (RTC_ADDRESS_CENTURY
, Century
);
714 if (Temp
== 0x19 || Temp
== 0x20) {
718 return EFI_DEVICE_ERROR
;
722 ConvertRtcTimeToEfiTime (
724 IN RTC_REGISTER_B RegisterB
736 // TODO: Time - add argument and description to function comment
737 // TODO: RegisterB - add argument and description to function comment
741 if ((Time
->Hour
) & 0x80) {
747 Time
->Hour
= (UINT8
) (Time
->Hour
& 0x7f);
749 if (RegisterB
.Bits
.DM
== 0) {
750 Time
->Year
= BcdToDecimal ((UINT8
) Time
->Year
);
751 Time
->Month
= BcdToDecimal (Time
->Month
);
752 Time
->Day
= BcdToDecimal (Time
->Day
);
753 Time
->Hour
= BcdToDecimal (Time
->Hour
);
754 Time
->Minute
= BcdToDecimal (Time
->Minute
);
755 Time
->Second
= BcdToDecimal (Time
->Second
);
758 // If time is in 12 hour format, convert it to 24 hour format
760 if (RegisterB
.Bits
.MIL
== 0) {
761 if (PM
&& Time
->Hour
< 12) {
762 Time
->Hour
= (UINT8
) (Time
->Hour
+ 12);
765 if (!PM
&& Time
->Hour
== 12) {
770 Time
->Nanosecond
= 0;
771 Time
->TimeZone
= EFI_UNSPECIFIED_TIMEZONE
;
788 // TODO: Timeout - add argument and description to function comment
789 // TODO: EFI_DEVICE_ERROR - add return value to function comment
790 // TODO: EFI_DEVICE_ERROR - add return value to function comment
791 // TODO: EFI_SUCCESS - add return value to function comment
793 RTC_REGISTER_A RegisterA
;
794 RTC_REGISTER_D RegisterD
;
797 // See if the RTC is functioning correctly
799 RegisterD
.Data
= RtcRead (RTC_ADDRESS_REGISTER_D
);
801 if (RegisterD
.Bits
.VRT
== 0) {
802 return EFI_DEVICE_ERROR
;
805 // Wait for up to 0.1 seconds for the RTC to be ready.
807 Timeout
= (Timeout
/ 10) + 1;
808 RegisterA
.Data
= RtcRead (RTC_ADDRESS_REGISTER_A
);
809 while (RegisterA
.Bits
.UIP
== 1 && Timeout
> 0) {
810 MicroSecondDelay (10);
811 RegisterA
.Data
= RtcRead (RTC_ADDRESS_REGISTER_A
);
815 RegisterD
.Data
= RtcRead (RTC_ADDRESS_REGISTER_D
);
816 if (Timeout
== 0 || RegisterD
.Bits
.VRT
== 0) {
817 return EFI_DEVICE_ERROR
;
835 // TODO: Time - add argument and description to function comment
836 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
837 // TODO: EFI_SUCCESS - add return value to function comment
839 if (Time
->Year
< 1998 ||
843 (!DayValid (Time
)) ||
847 Time
->Nanosecond
> 999999999 ||
848 (!(Time
->TimeZone
== EFI_UNSPECIFIED_TIMEZONE
|| (Time
->TimeZone
>= -1440 && Time
->TimeZone
<= 1440))) ||
849 (Time
->Daylight
& (~(EFI_TIME_ADJUST_DAYLIGHT
| EFI_TIME_IN_DAYLIGHT
)))
851 return EFI_INVALID_PARAMETER
;
865 TODO: Add function description
869 Time - TODO: add argument description
873 TODO: add return values
880 Time
->Day
> mDayOfMonth
[Time
->Month
- 1] ||
881 (Time
->Month
== 2 && (!IsLeapYear (Time
) && Time
->Day
> 28))
897 TODO: Add function description
901 Time - TODO: add argument description
905 TODO: add return values
909 if (Time
->Year
% 4 == 0) {
910 if (Time
->Year
% 100 == 0) {
911 if (Time
->Year
% 400 == 0) {
925 ConvertEfiTimeToRtcTime (
927 IN RTC_REGISTER_B RegisterB
,
939 // TODO: Time - add argument and description to function comment
940 // TODO: RegisterB - add argument and description to function comment
941 // TODO: Century - add argument and description to function comment
947 // Adjust hour field if RTC in in 12 hour mode
949 if (RegisterB
.Bits
.MIL
== 0) {
950 if (Time
->Hour
< 12) {
954 if (Time
->Hour
>= 13) {
955 Time
->Hour
= (UINT8
) (Time
->Hour
- 12);
956 } else if (Time
->Hour
== 0) {
961 // Set the Time/Date/Daylight Savings values.
963 *Century
= DecimaltoBcd ((UINT8
) (Time
->Year
/ 100));
965 Time
->Year
= (UINT16
) (Time
->Year
% 100);
967 if (RegisterB
.Bits
.DM
== 0) {
968 Time
->Year
= DecimaltoBcd ((UINT8
) Time
->Year
);
969 Time
->Month
= DecimaltoBcd (Time
->Month
);
970 Time
->Day
= DecimaltoBcd (Time
->Day
);
971 Time
->Hour
= DecimaltoBcd (Time
->Hour
);
972 Time
->Minute
= DecimaltoBcd (Time
->Minute
);
973 Time
->Second
= DecimaltoBcd (Time
->Second
);
976 // If we are in 12 hour mode and PM is set, then set bit 7 of the Hour field.
978 if (RegisterB
.Bits
.MIL
== 0 && PM
) {
979 Time
->Hour
= (UINT8
) (Time
->Hour
| 0x80);
992 Judge whether two days are adjacent.
1001 TRUE - The interval of two days are within one day.
1002 FALSE - The interval of two days exceed ony day or parameter error.
1006 BOOLEAN Adjacent
= FALSE
;
1008 if (From
->Year
== To
->Year
) {
1009 if (From
->Month
== To
->Month
) {
1010 if ((From
->Day
+ 1) == To
->Day
) {
1011 if ((CompareHMS(From
, To
) >= 0)) {
1014 } else if (From
->Day
== To
->Day
) {
1015 if ((CompareHMS(From
, To
) <= 0)) {
1019 } else if (((From
->Month
+ 1) == To
->Month
) && (To
->Day
== 1)) {
1020 if ((From
->Month
== 2) && !IsLeapYear(From
)) {
1021 if (From
->Day
== 28) {
1022 if ((CompareHMS(From
, To
) >= 0)) {
1026 } else if (From
->Day
== mDayOfMonth
[From
->Month
- 1]) {
1027 if ((CompareHMS(From
, To
) >= 0)) {
1032 } else if (((From
->Year
+ 1) == To
->Year
) &&
1033 (From
->Month
== 12) &&
1034 (From
->Day
== 31) &&
1037 if ((CompareHMS(From
, To
) >= 0)) {
1051 Routine Description:
1058 // TODO: DecValue - add argument and description to function comment
1063 High
= DecValue
/ 10;
1064 Low
= DecValue
- (High
* 10);
1066 return (UINT8
) (Low
+ (High
<< 4));