Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_rtc.c
1 #include <bc_rtc.h>
2 #include <bc_irq.h>
3 #include <stm32l0xx.h>
4 
5 #define _BC_RTC_LEAP_YEAR(year) ((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0))
6 #define _BC_RTC_DAYS_IN_YEAR(x) _BC_RTC_LEAP_YEAR(x) ? 366 : 365
7 #define _BC_RTC_OFFSET_YEAR 1970
8 #define _BC_RTC_SECONDS_PER_DAY 86400
9 #define _BC_RTC_SECONDS_PER_HOUR 3600
10 #define _BC_RTC_SECONDS_PER_MINUTE 60
11 
12 // Days in a month
13 uint8_t _bc_rtc_months[2][12] =
14  {
15  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // Not leap year
16  {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // Leap year
17 };
18 
19 void bc_rtc_init(void)
20 {
21 }
22 
24 {
25  uint32_t days = 0, seconds = 0;
26  uint16_t i;
27  // Year is below offset year
28  if (rtc->year < _BC_RTC_OFFSET_YEAR)
29  {
30  return 0;
31  }
32  // Days in back years
33  for (i = _BC_RTC_OFFSET_YEAR; i < rtc->year; i++)
34  {
35  days += _BC_RTC_DAYS_IN_YEAR(i);
36  }
37  // Days in current year
38  for (i = 1; i < rtc->month; i++)
39  {
40  days += _bc_rtc_months[_BC_RTC_LEAP_YEAR(rtc->year)][i - 1];
41  }
42  // Day starts with 1
43  days += rtc->date - 1;
44  seconds = days * _BC_RTC_SECONDS_PER_DAY;
45  seconds += rtc->hours * _BC_RTC_SECONDS_PER_HOUR;
46  seconds += rtc->minutes * _BC_RTC_SECONDS_PER_MINUTE;
47  seconds += rtc->seconds;
48 
49  return seconds;
50 }
51 
53 {
54  uint32_t unix;
55 
56  // Format hours
57  uint32_t tr = RTC->TR;
58  rtc->hours = 10 * ((tr & RTC_TR_HT_Msk) >> RTC_TR_HT_Pos) + ((tr & RTC_TR_HU_Msk) >> RTC_TR_HU_Pos);
59  rtc->minutes = 10 * ((tr & RTC_TR_MNT_Msk) >> RTC_TR_MNT_Pos) + ((tr & RTC_TR_MNU_Msk) >> RTC_TR_MNU_Pos);
60  rtc->seconds = 10 * ((tr & RTC_TR_ST_Msk) >> RTC_TR_ST_Pos) + ((tr & RTC_TR_SU_Msk) >> RTC_TR_SU_Pos);
61 
62  // Get subseconds
63  rtc->subseconds = RTC->SSR;
64 
65  // Format date
66  uint32_t dr = RTC->DR;
67  rtc->year = 2000 + 10 * ((dr & RTC_DR_YT_Msk) >> RTC_DR_YT_Pos) + ((dr & RTC_DR_YU_Msk) >> RTC_DR_YU_Pos);
68  rtc->month = 10 * ((dr & RTC_DR_MT_Msk) >> RTC_DR_MT_Pos) + ((dr & RTC_DR_MU_Msk) >> RTC_DR_MU_Pos);
69  rtc->date = 10 * ((dr & RTC_DR_DT_Msk) >> RTC_DR_DT_Pos) + ((dr & RTC_DR_DU_Msk) >> RTC_DR_DU_Pos);
70  rtc->week_day = (dr & RTC_DR_WDU_Msk) >> RTC_DR_WDU_Pos;
71 
72  // Calculate unix offset
73  unix = bc_rtc_rtc_to_timestamp(rtc);
74  rtc->timestamp = unix;
75 }
76 
78 {
79  if (rtc->year < 2000 || rtc->year > 2099)
80  {
81  return false;
82  }
83 
84  // Disable write protection
85  RTC->WPR = 0xca;
86  RTC->WPR = 0x53;
87 
88  // Enable Init Mode
89  RTC->ISR |= RTC_ISR_INIT;
90 
91  while ((RTC->ISR & RTC_ISR_INITF) == 0)
92  {
93  continue;
94  }
95 
96  // Format hours
97  uint32_t tr;
98  tr = (rtc->hours / 10) << RTC_TR_HT_Pos |
99  (rtc->hours % 10) << RTC_TR_HU_Pos |
100  (rtc->minutes / 10) << RTC_TR_MNT_Pos |
101  (rtc->minutes % 10) << RTC_TR_MNU_Pos |
102  (rtc->seconds / 10) << RTC_TR_ST_Pos |
103  (rtc->seconds % 10) << RTC_TR_SU_Pos;
104 
105  RTC->TR = tr;
106 
107  // Format date
108  uint32_t dr;
109 
110  dr = ((rtc->year - 2000) / 10) << RTC_DR_YT_Pos |
111  ((rtc->year - 2000) % 10) << RTC_DR_YU_Pos |
112  (rtc->month / 10) << RTC_DR_MT_Pos |
113  (rtc->month % 10) << RTC_DR_MU_Pos |
114  (rtc->date / 10) << RTC_DR_DT_Pos |
115  (rtc->date % 10) << RTC_DR_DU_Pos;
116 
117  RTC->DR = dr;
118 
119  // Disable Init Mode
120  RTC->ISR &= ~RTC_ISR_INIT;
121 
122  // Enable Write Protection
123  RTC->WPR = 0xff;
124 
125  return true;
126 }
uint8_t seconds
Seconds parameter, from 00 to 59.
Definition: bc_rtc.h:17
uint8_t hours
Hours parameter, 24Hour mode, 00 to 23.
Definition: bc_rtc.h:20
void bc_rtc_get_date_time(bc_rtc_t *rtc)
Get date and time from RTC.
Definition: bc_rtc.c:52
uint32_t timestamp
Seconds from 01.01.1970 00:00:00.
Definition: bc_rtc.h:25
uint8_t week_day
Day in a week, from 1 to 7.
Definition: bc_rtc.h:21
uint8_t minutes
Minutes parameter, from 00 to 59.
Definition: bc_rtc.h:19
uint8_t month
Month in a year, 1 to 12.
Definition: bc_rtc.h:23
uint16_t subseconds
Subsecond downcounter. When it reaches zero, it's reload value is the same as RTC_SYNC_PREDIV.
Definition: bc_rtc.h:18
uint32_t bc_rtc_rtc_to_timestamp(bc_rtc_t *rtc)
Covert RTC to timestamp.
Definition: bc_rtc.c:23
void bc_rtc_init(void)
Initialize real-time clock.
Definition: bc_rtc.c:19
uint8_t date
Date in a month, 1 to 31.
Definition: bc_rtc.h:22
bool bc_rtc_set_date_time(bc_rtc_t *rtc)
Set gate and time to RTC.
Definition: bc_rtc.c:77
uint16_t year
Year parameter, 2000 to 2099.
Definition: bc_rtc.h:24
RTC date and time structure.
Definition: bc_rtc.h:15