32
32
static int rtc_inited = 0 ;
33
33
34
34
void rtc_init (void ) {
35
- RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR | RCC_APB1Periph_BKP , ENABLE ); // Enable PWR and Backup clock
35
+ RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR , ENABLE ); // Enable PWR clock
36
36
37
- PWR_BackupAccessCmd (ENABLE ); // Allow access to Backup Domain
38
-
39
- BKP_DeInit (); // Reset Backup Domain
37
+ PWR_RTCAccessCmd (ENABLE ); // Enable access to RTC
38
+
39
+ // Note: the LSI is used as RTC source clock
40
+ // The RTC Clock may vary due to LSI frequency dispersion.
41
+
42
+ RCC_LSICmd (ENABLE ); // Enable LSI
40
43
41
- // Uncomment these lines if you use the LSE
42
- // Enable LSE and wait till it's ready
43
- //RCC_LSEConfig(RCC_LSE_ON);
44
- //while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}
45
- //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC Clock Source
46
-
47
- // Uncomment these lines if you use the LSI
48
- // Enable LSI and wait till it's ready
49
- RCC_LSICmd (ENABLE );
50
- while (RCC_GetFlagStatus (RCC_FLAG_LSIRDY ) == RESET ) {}
44
+ while (RCC_GetFlagStatus (RCC_FLAG_LSIRDY ) == RESET ) {} // Wait until ready
45
+
51
46
RCC_RTCCLKConfig (RCC_RTCCLKSource_LSI ); // Select LSI as RTC Clock Source
52
47
53
48
RCC_RTCCLKCmd (ENABLE ); // Enable RTC Clock
54
49
55
50
RTC_WaitForSynchro (); // Wait for RTC registers synchronization
56
-
57
- RTC_WaitForLastTask (); // Wait until last write operation on RTC registers has finished
58
51
59
- // Set RTC period to 1 sec
60
- // For LSE: prescaler = RTCCLK/RTC period = 32768Hz/1Hz = 32768
61
- // For LSI: prescaler = RTCCLK/RTC period = 40000Hz/1Hz = 40000
62
- RTC_SetPrescaler (39999 );
52
+ uint32_t lsi_freq = 40000 ; // *** TODO** To be measured precisely using a timer input capture
53
+
54
+ RTC_InitTypeDef RTC_InitStructure ;
55
+ RTC_InitStructure .RTC_AsynchPrediv = 127 ;
56
+ RTC_InitStructure .RTC_SynchPrediv = (lsi_freq / 128 ) - 1 ;
57
+ RTC_InitStructure .RTC_HourFormat = RTC_HourFormat_24 ;
58
+ RTC_Init (& RTC_InitStructure );
63
59
64
- RTC_WaitForLastTask ( ); // Wait until last write operation on RTC registers has finished
60
+ PWR_RTCAccessCmd ( DISABLE ); // Disable access to RTC
65
61
66
62
rtc_inited = 1 ;
67
63
}
@@ -75,12 +71,67 @@ int rtc_isenabled(void) {
75
71
return rtc_inited ;
76
72
}
77
73
74
+ /*
75
+ RTC Registers
76
+ RTC_WeekDay 1=monday, 2=tuesday, ..., 7=sunday
77
+ RTC_Month 1=january, 2=february, ..., 12=december
78
+ RTC_Date day of the month 1-31
79
+ RTC_Year year 0-99
80
+ struct tm
81
+ tm_sec seconds after the minute 0-61
82
+ tm_min minutes after the hour 0-59
83
+ tm_hour hours since midnight 0-23
84
+ tm_mday day of the month 1-31
85
+ tm_mon months since January 0-11
86
+ tm_year years since 1900
87
+ tm_wday days since Sunday 0-6
88
+ tm_yday days since January 1 0-365
89
+ tm_isdst Daylight Saving Time flag
90
+ */
78
91
time_t rtc_read (void ) {
79
- return (time_t )RTC_GetCounter ();
92
+ RTC_DateTypeDef dateStruct ;
93
+ RTC_TimeTypeDef timeStruct ;
94
+ struct tm timeinfo ;
95
+
96
+ // Read actual date and time
97
+ RTC_GetTime (RTC_Format_BIN , & timeStruct );
98
+ RTC_GetDate (RTC_Format_BIN , & dateStruct );
99
+
100
+ // Setup a tm structure based on the RTC
101
+ timeinfo .tm_wday = dateStruct .RTC_WeekDay ;
102
+ timeinfo .tm_mon = dateStruct .RTC_Month - 1 ;
103
+ timeinfo .tm_mday = dateStruct .RTC_Date ;
104
+ timeinfo .tm_year = dateStruct .RTC_Year + 100 ;
105
+ timeinfo .tm_hour = timeStruct .RTC_Hours ;
106
+ timeinfo .tm_min = timeStruct .RTC_Minutes ;
107
+ timeinfo .tm_sec = timeStruct .RTC_Seconds ;
108
+
109
+ // Convert to timestamp
110
+ time_t t = mktime (& timeinfo );
111
+
112
+ return t ;
80
113
}
81
114
82
115
void rtc_write (time_t t ) {
83
- RTC_WaitForLastTask (); // Wait until last write operation on RTC registers has finished
84
- RTC_SetCounter (t ); // Change the current time
85
- RTC_WaitForLastTask (); // Wait until last write operation on RTC registers has finished
116
+ RTC_DateTypeDef dateStruct ;
117
+ RTC_TimeTypeDef timeStruct ;
118
+
119
+ // Convert the time into a tm
120
+ struct tm * timeinfo = localtime (& t );
121
+
122
+ // Fill RTC structures
123
+ dateStruct .RTC_WeekDay = timeinfo -> tm_wday ;
124
+ dateStruct .RTC_Month = timeinfo -> tm_mon + 1 ;
125
+ dateStruct .RTC_Date = timeinfo -> tm_mday ;
126
+ dateStruct .RTC_Year = timeinfo -> tm_year - 100 ;
127
+ timeStruct .RTC_Hours = timeinfo -> tm_hour ;
128
+ timeStruct .RTC_Minutes = timeinfo -> tm_min ;
129
+ timeStruct .RTC_Seconds = timeinfo -> tm_sec ;
130
+ timeStruct .RTC_H12 = RTC_HourFormat_24 ;
131
+
132
+ // Change the RTC current date/time
133
+ PWR_RTCAccessCmd (ENABLE ); // Enable access to RTC
134
+ RTC_SetDate (RTC_Format_BIN , & dateStruct );
135
+ RTC_SetTime (RTC_Format_BIN , & timeStruct );
136
+ PWR_RTCAccessCmd (DISABLE ); // Disable access to RTC
86
137
}
0 commit comments