RTC.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. Copyright (C) Dean Camera, 2018.
  3. dean [at] fourwalledcubicle [dot] com
  4. www.lufa-lib.org
  5. */
  6. #include "RTC.h"
  7. #if defined(DUMMY_RTC)
  8. /** Current dummy RTC time and date */
  9. static volatile TimeDate_t DummyRTC_Count;
  10. void RTC_Init(void)
  11. {
  12. DummyRTC_Count.Hour = 0;
  13. DummyRTC_Count.Minute = 0;
  14. DummyRTC_Count.Second = 0;
  15. DummyRTC_Count.Day = 1;
  16. DummyRTC_Count.Month = 1;
  17. DummyRTC_Count.Year = 00;
  18. }
  19. void RTC_Tick500ms(void)
  20. {
  21. static bool HalfSecondElapsed = false;
  22. HalfSecondElapsed = !HalfSecondElapsed;
  23. if (HalfSecondElapsed == false)
  24. return;
  25. if (++DummyRTC_Count.Second < 60)
  26. return;
  27. DummyRTC_Count.Second = 0;
  28. if (++DummyRTC_Count.Minute < 60)
  29. return;
  30. DummyRTC_Count.Minute = 0;
  31. if (++DummyRTC_Count.Hour < 24)
  32. return;
  33. DummyRTC_Count.Hour = 0;
  34. static const char MonthLength[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  35. uint8_t DaysInMonth = MonthLength[DummyRTC_Count.Month - 1];
  36. /* Check if we need to account for a leap year */
  37. if ((DummyRTC_Count.Month == 2) &&
  38. ((!(DummyRTC_Count.Year % 400)) || ((DummyRTC_Count.Year % 100) && !(DummyRTC_Count.Year % 4))))
  39. {
  40. DaysInMonth++;
  41. }
  42. if (++DummyRTC_Count.Day <= DaysInMonth)
  43. return;
  44. DummyRTC_Count.Day = 1;
  45. if (++DummyRTC_Count.Month <= 12)
  46. return;
  47. DummyRTC_Count.Month = 1;
  48. DummyRTC_Count.Year++;
  49. }
  50. bool RTC_SetTimeDate(const TimeDate_t* NewTimeDate)
  51. {
  52. GlobalInterruptDisable();
  53. DummyRTC_Count = *NewTimeDate;
  54. GlobalInterruptEnable();
  55. return true;
  56. }
  57. bool RTC_GetTimeDate(TimeDate_t* const TimeDate)
  58. {
  59. GlobalInterruptDisable();
  60. *TimeDate = DummyRTC_Count;
  61. GlobalInterruptEnable();
  62. return true;
  63. }
  64. #else
  65. void RTC_Init(void)
  66. {
  67. /* Unused for a real external DS1307 RTC device */
  68. }
  69. void RTC_Tick500ms(void)
  70. {
  71. /* Unused for a real external DS1307 RTC device */
  72. }
  73. bool RTC_SetTimeDate(const TimeDate_t* NewTimeDate)
  74. {
  75. DS1307_DateTimeRegs_t NewRegValues;
  76. const uint8_t WriteAddress = 0;
  77. // Convert new time data to the DS1307's time register layout
  78. NewRegValues.Byte1.Fields.TenSec = (NewTimeDate->Second / 10);
  79. NewRegValues.Byte1.Fields.Sec = (NewTimeDate->Second % 10);
  80. NewRegValues.Byte1.Fields.CH = false;
  81. NewRegValues.Byte2.Fields.TenMin = (NewTimeDate->Minute / 10);
  82. NewRegValues.Byte2.Fields.Min = (NewTimeDate->Minute % 10);
  83. NewRegValues.Byte3.Fields.TenHour = (NewTimeDate->Hour / 10);
  84. NewRegValues.Byte3.Fields.Hour = (NewTimeDate->Hour % 10);
  85. NewRegValues.Byte3.Fields.TwelveHourMode = false;
  86. // Convert new date data to the DS1307's date register layout
  87. NewRegValues.Byte4.Fields.DayOfWeek = 0;
  88. NewRegValues.Byte5.Fields.TenDay = (NewTimeDate->Day / 10);
  89. NewRegValues.Byte5.Fields.Day = (NewTimeDate->Day % 10);
  90. NewRegValues.Byte6.Fields.TenMonth = (NewTimeDate->Month / 10);
  91. NewRegValues.Byte6.Fields.Month = (NewTimeDate->Month % 10);
  92. NewRegValues.Byte7.Fields.TenYear = (NewTimeDate->Year / 10);
  93. NewRegValues.Byte7.Fields.Year = (NewTimeDate->Year % 10);
  94. // Write the new Time and Date into the DS1307
  95. if (TWI_WritePacket(DS1307_ADDRESS, 10, &WriteAddress, sizeof(WriteAddress),
  96. (uint8_t*)&NewRegValues, sizeof(DS1307_DateTimeRegs_t)) != TWI_ERROR_NoError)
  97. {
  98. return false;
  99. }
  100. return true;
  101. }
  102. bool RTC_GetTimeDate(TimeDate_t* const TimeDate)
  103. {
  104. DS1307_DateTimeRegs_t CurrentRegValues;
  105. const uint8_t ReadAddress = 0;
  106. // Read in the stored Time and Date from the DS1307
  107. if (TWI_ReadPacket(DS1307_ADDRESS, 10, &ReadAddress, sizeof(ReadAddress),
  108. (uint8_t*)&CurrentRegValues, sizeof(DS1307_DateTimeRegs_t)) != TWI_ERROR_NoError)
  109. {
  110. return false;
  111. }
  112. // Convert stored time value into decimal
  113. TimeDate->Second = (CurrentRegValues.Byte1.Fields.TenSec * 10) + CurrentRegValues.Byte1.Fields.Sec;
  114. TimeDate->Minute = (CurrentRegValues.Byte2.Fields.TenMin * 10) + CurrentRegValues.Byte2.Fields.Min;
  115. TimeDate->Hour = (CurrentRegValues.Byte3.Fields.TenHour * 10) + CurrentRegValues.Byte3.Fields.Hour;
  116. // Convert stored date value into decimal
  117. TimeDate->Day = (CurrentRegValues.Byte5.Fields.TenDay * 10) + CurrentRegValues.Byte5.Fields.Day;
  118. TimeDate->Month = (CurrentRegValues.Byte6.Fields.TenMonth * 10) + CurrentRegValues.Byte6.Fields.Month;
  119. TimeDate->Year = (CurrentRegValues.Byte7.Fields.TenYear * 10) + CurrentRegValues.Byte7.Fields.Year;
  120. return true;
  121. }
  122. #endif