1
1
/* mbed Microcontroller Library
2
2
*******************************************************************************
3
- * Copyright (c) 2014 , STMicroelectronics
3
+ * Copyright (c) 2016 , STMicroelectronics
4
4
* All rights reserved.
5
5
*
6
6
* Redistribution and use in source and binary forms, with or without
28
28
*******************************************************************************
29
29
*/
30
30
#include "rtc_api.h"
31
+ #include "rtc_api_hal.h"
31
32
32
33
#if DEVICE_RTC
33
34
34
35
#include "mbed_error.h"
35
36
36
37
#if DEVICE_RTC_LSI
37
- static int rtc_inited = 0 ;
38
+ static int rtc_inited = 0 ;
38
39
#endif
39
40
40
41
static RTC_HandleTypeDef RtcHandle ;
41
42
43
+ #if DEVICE_RTC_LSI
44
+ #define RTC_CLOCK LSI_VALUE
45
+ #else
46
+ #define RTC_CLOCK LSE_VALUE
47
+ #endif
48
+
49
+ #if DEVICE_LOWPOWERTIMER
50
+ #define RTC_ASYNCH_PREDIV ((RTC_CLOCK - 1) / 0x8000)
51
+ #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
52
+ #else
53
+ #define RTC_ASYNCH_PREDIV (0x007F)
54
+ #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
55
+ #endif
56
+
57
+ #if DEVICE_LOWPOWERTIMER
58
+ static void (* irq_handler )(void );
59
+ static void RTC_IRQHandler ();
60
+ #endif
61
+
42
62
void rtc_init (void )
43
63
{
44
64
RCC_OscInitTypeDef RCC_OscInitStruct ;
45
- uint32_t rtc_freq = 0 ;
46
65
47
66
#if DEVICE_RTC_LSI
67
+ if (rtc_inited ) return ;
48
68
rtc_inited = 1 ;
49
69
#endif
50
70
@@ -58,13 +78,11 @@ void rtc_init(void)
58
78
if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) == HAL_OK ) {
59
79
// Connect LSE to RTC
60
80
__HAL_RCC_RTC_CONFIG (RCC_RTCCLKSOURCE_LSE );
61
- rtc_freq = LSE_VALUE ;
62
- }
63
- else {
64
- error ("RTC error: LSE clock initialization failed." );
81
+ } else {
82
+ error ("RTC error: LSE clock initialization failed." );
65
83
}
66
84
#else
67
- // Enable Power clock
85
+ // Enable Power clock
68
86
__PWR_CLK_ENABLE ();
69
87
70
88
// Enable access to Backup domain
@@ -73,35 +91,46 @@ void rtc_init(void)
73
91
// Reset Backup domain
74
92
__HAL_RCC_BACKUPRESET_FORCE ();
75
93
__HAL_RCC_BACKUPRESET_RELEASE ();
76
-
77
- // Enable LSI clock
78
- RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE ;
79
- RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ; // Mandatory, otherwise the PLL is reconfigured!
80
- RCC_OscInitStruct .LSEState = RCC_LSE_OFF ;
81
- RCC_OscInitStruct .LSIState = RCC_LSI_ON ;
82
- if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
83
- error ("RTC error: LSI clock initialization failed." );
84
- }
85
- // Connect LSI to RTC
86
- __HAL_RCC_RTC_CONFIG (RCC_RTCCLKSOURCE_LSI );
87
- // Note: The LSI clock can be measured precisely using a timer input capture.
88
- rtc_freq = LSI_VALUE ;
89
- #endif
90
94
95
+ // Enable LSI clock
96
+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE ;
97
+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ; // Mandatory, otherwise the PLL is reconfigured!
98
+ RCC_OscInitStruct .LSEState = RCC_LSE_OFF ;
99
+ RCC_OscInitStruct .LSIState = RCC_LSI_ON ;
100
+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
101
+ error ("RTC error: LSI clock initialization failed." );
102
+ }
103
+ // Connect LSI to RTC
104
+ __HAL_RCC_RTC_CONFIG (RCC_RTCCLKSOURCE_LSI );
105
+ #endif
91
106
92
107
// Enable RTC
93
108
__HAL_RCC_RTC_ENABLE ();
94
109
95
110
RtcHandle .Init .HourFormat = RTC_HOURFORMAT_24 ;
96
- RtcHandle .Init .AsynchPrediv = 127 ;
97
- RtcHandle .Init .SynchPrediv = ( rtc_freq / 128 ) - 1 ;
111
+ RtcHandle .Init .AsynchPrediv = RTC_ASYNCH_PREDIV ;
112
+ RtcHandle .Init .SynchPrediv = RTC_SYNCH_PREDIV ;
98
113
RtcHandle .Init .OutPut = RTC_OUTPUT_DISABLE ;
99
114
RtcHandle .Init .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH ;
100
115
RtcHandle .Init .OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN ;
101
116
102
117
if (HAL_RTC_Init (& RtcHandle ) != HAL_OK ) {
103
118
error ("RTC error: RTC initialization failed." );
104
119
}
120
+
121
+ #if DEVICE_LOWPOWERTIMER
122
+ #if DEVICE_RTC_LSI
123
+ rtc_write (0 );
124
+ #else
125
+ if (!rtc_isenabled ()) {
126
+ rtc_write (0 );
127
+ }
128
+ #endif
129
+ NVIC_ClearPendingIRQ (RTC_WKUP_IRQn );
130
+ NVIC_DisableIRQ (RTC_WKUP_IRQn );
131
+ NVIC_SetVector (RTC_WKUP_IRQn , (uint32_t )RTC_IRQHandler );
132
+ NVIC_EnableIRQ (RTC_WKUP_IRQn );
133
+ #endif
105
134
}
106
135
107
136
void rtc_free (void )
@@ -218,4 +247,50 @@ void rtc_write(time_t t)
218
247
HAL_RTC_SetTime (& RtcHandle , & timeStruct , FORMAT_BIN );
219
248
}
220
249
250
+ #if DEVICE_LOWPOWERTIMER
251
+
252
+ static void RTC_IRQHandler ()
253
+ {
254
+ HAL_RTCEx_WakeUpTimerIRQHandler (& RtcHandle );
255
+ }
256
+
257
+ void HAL_RTCEx_WakeUpTimerEventCallback (RTC_HandleTypeDef * hrtc )
258
+ {
259
+ if (irq_handler ) {
260
+ // Fire the user callback
261
+ irq_handler ();
262
+ }
263
+ }
264
+
265
+ void rtc_set_irq_handler (uint32_t handler )
266
+ {
267
+ irq_handler = (void (* )(void ))handler ;
268
+ }
269
+
270
+ uint32_t rtc_read_subseconds (void )
271
+ {
272
+ return 1000000.f * ((double )(RTC_SYNCH_PREDIV - RTC -> SSR ) / (RTC_SYNCH_PREDIV + 1 ));
273
+ }
274
+
275
+ void rtc_set_wake_up_timer (uint32_t delta )
276
+ {
277
+ uint32_t wake_up_counter = delta / (2000000 / RTC_CLOCK );
278
+
279
+ if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , wake_up_counter ,
280
+ RTC_WAKEUPCLOCK_RTCCLK_DIV2 ) != HAL_OK ) {
281
+ error ("Set wake up timer failed\n" );
282
+ }
283
+ }
284
+
285
+ void rtc_deactivate_wake_up_timer (void )
286
+ {
287
+ HAL_RTCEx_DeactivateWakeUpTimer (& RtcHandle );
288
+ }
289
+
290
+ void rtc_synchronize (void )
291
+ {
292
+ HAL_RTC_WaitForSynchro (& RtcHandle );
293
+ }
294
+ #endif // DEVICE_LOWPOWERTIMER
295
+
221
296
#endif
0 commit comments