datetime.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Date/time handling
  3. *
  4. * Copyright (c) 2013 Michael Buesch <m@bues.ch>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. */
  20. #include "datetime.h"
  21. /* Convert a binary byte to a BCD value.
  22. * value: The binary value.
  23. * Returns the BCD value.
  24. */
  25. static uint8_t byte_to_bcd(uint8_t value)
  26. {
  27. uint8_t bcd;
  28. bcd = value % 10;
  29. value /= 10;
  30. bcd |= (value % 10) << 4;
  31. return bcd;
  32. }
  33. /* Convert a BCD value to a binary byte.
  34. * bcd: The BCD value.
  35. * Returns the binary value.
  36. */
  37. static uint8_t bcd_to_byte(uint8_t bcd)
  38. {
  39. uint8_t value;
  40. value = bcd & 0x0F;
  41. value += ((bcd >> 4) & 0x0F) * 10;
  42. return value;
  43. }
  44. /* Convert an rtc_time from binary to BCD.
  45. * bcd_time: The destination buffer.
  46. * time: The source buffer.
  47. */
  48. void rtc_time_to_bcd(struct rtc_time *bcd_time,
  49. const struct rtc_time *time)
  50. {
  51. bcd_time->second = byte_to_bcd(time->second);
  52. bcd_time->minute = byte_to_bcd(time->minute);
  53. bcd_time->hour = byte_to_bcd(time->hour);
  54. bcd_time->day = byte_to_bcd(time->day);
  55. bcd_time->month = byte_to_bcd(time->month);
  56. bcd_time->year = byte_to_bcd(time->year);
  57. bcd_time->day_of_week = time->day_of_week;
  58. }
  59. /* Convert an rtc_time from BCD to binary.
  60. * time: The destination buffer.
  61. * bcd_time: The source buffer.
  62. */
  63. void rtc_time_from_bcd(struct rtc_time *time,
  64. const struct rtc_time *bcd_time)
  65. {
  66. time->second = bcd_to_byte(bcd_time->second);
  67. time->minute = bcd_to_byte(bcd_time->minute);
  68. time->hour = bcd_to_byte(bcd_time->hour);
  69. time->day = bcd_to_byte(bcd_time->day);
  70. time->month = bcd_to_byte(bcd_time->month);
  71. time->year = bcd_to_byte(bcd_time->year);
  72. time->day_of_week = bcd_time->day_of_week;
  73. }
  74. /* Get the time-of-day from an rtc_time structure.
  75. * time: The RTC time.
  76. * Returns a time_of_day_t object.
  77. */
  78. time_of_day_t rtc_get_time_of_day(const struct rtc_time *time)
  79. {
  80. uint32_t seconds;
  81. /* Add the number of seconds. */
  82. seconds = time->second;
  83. seconds += (uint16_t)time->minute * 60;
  84. seconds += (uint32_t)time->hour * 60 * 60;
  85. /* Return the number of seconds, divided by two.
  86. * Divide by two, because time_of_day_t is a double-second count.
  87. */
  88. return seconds / 2;
  89. }
  90. /* Get the timestamp from an rtc_time structure.
  91. * time: The RTC time.
  92. * Returns a timestamp_t object.
  93. * See the docs of timestamp_t for documentation of the format.
  94. */
  95. timestamp_t rtc_get_timestamp(const struct rtc_time *time)
  96. {
  97. timestamp_t s = 0;
  98. s |= (timestamp_t)(clamp(time->second, 0, 59) & 0x3F) << 0;
  99. s |= (timestamp_t)(clamp(time->minute, 0, 59) & 0x3F) << 6;
  100. s |= (timestamp_t)(clamp(time->hour, 0, 23) & 0x1F) << 12;
  101. s |= (timestamp_t)(clamp(time->day, 0, 30) & 0x1F) << 17;
  102. s |= (timestamp_t)(clamp(time->month, 0, 11) & 0x0F) << 22;
  103. s |= (timestamp_t)(clamp(time->year, 0, 63) & 0x3F) << 26;
  104. return s;
  105. }