1
1
/* mbed Microcontroller Library
2
2
*******************************************************************************
3
- * Copyright (c) 2016 , STMicroelectronics
3
+ * Copyright (c) 2017 , STMicroelectronics
4
4
* All rights reserved.
5
5
*
6
6
* Redistribution and use in source and binary forms, with or without
27
27
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
*******************************************************************************
29
29
*/
30
+
30
31
#if DEVICE_RTC
31
32
32
- #include "rtc_api.h"
33
33
#include "rtc_api_hal.h"
34
34
#include "mbed_error.h"
35
35
#include "mbed_mktime.h"
36
36
37
37
static RTC_HandleTypeDef RtcHandle ;
38
38
39
- #if RTC_LSI
40
- #define RTC_CLOCK LSI_VALUE
41
- #else
42
- #define RTC_CLOCK LSE_VALUE
43
- #endif
44
-
45
39
#if DEVICE_LOWPOWERTIMER
46
40
#define RTC_ASYNCH_PREDIV ((RTC_CLOCK - 1) / 0x8000)
47
- #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
48
41
#else
49
42
#define RTC_ASYNCH_PREDIV (0x007F)
50
- #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
51
43
#endif
52
44
45
+ #define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1)
46
+
53
47
#if DEVICE_LOWPOWERTIMER
54
48
static void (* irq_handler )(void );
55
49
static void RTC_IRQHandler (void );
@@ -63,28 +57,29 @@ void rtc_init(void)
63
57
// Enable access to Backup domain
64
58
HAL_PWR_EnableBkUpAccess ();
65
59
66
- RtcHandle .Instance = RTC ;
67
- RtcHandle .State = HAL_RTC_STATE_RESET ;
68
-
69
- #if !RTC_LSI
60
+ #if !RTC_LSI /* => LSE */
70
61
RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_LSE ;
71
62
RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ; // Mandatory, otherwise the PLL is reconfigured!
72
63
RCC_OscInitStruct .LSEState = RCC_LSE_ON ;
73
64
RCC_OscInitStruct .LSIState = RCC_LSI_OFF ;
74
65
75
- if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) == HAL_OK ) {
76
- __HAL_RCC_RTC_CLKPRESCALER (RCC_RTCCLKSOURCE_LSE );
77
- __HAL_RCC_RTC_CONFIG (RCC_RTCCLKSOURCE_LSE );
78
- } else {
66
+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
79
67
error ("Cannot initialize RTC with LSE\n" );
80
68
}
81
69
70
+ __HAL_RCC_RTC_CLKPRESCALER (RCC_RTCCLKSOURCE_LSE );
71
+ __HAL_RCC_RTC_CONFIG (RCC_RTCCLKSOURCE_LSE );
72
+
82
73
PeriphClkInitStruct .PeriphClockSelection = RCC_PERIPHCLK_RTC ;
83
74
PeriphClkInitStruct .RTCClockSelection = RCC_RTCCLKSOURCE_LSE ;
84
75
if (HAL_RCCEx_PeriphCLKConfig (& PeriphClkInitStruct ) != HAL_OK ) {
85
76
error ("PeriphClkInitStruct RTC failed with LSE\n" );
86
77
}
87
- #else /* !RTC_LSI */
78
+
79
+ if (rtc_isenabled ()) return ;
80
+ #else /* => RTC_LSI */
81
+ if (rtc_isenabled ()) return ;
82
+
88
83
__HAL_RCC_PWR_CLK_ENABLE ();
89
84
90
85
// Reset Backup domain
@@ -113,6 +108,9 @@ void rtc_init(void)
113
108
// Enable RTC
114
109
__HAL_RCC_RTC_ENABLE ();
115
110
111
+ RtcHandle .Instance = RTC ;
112
+ RtcHandle .State = HAL_RTC_STATE_RESET ;
113
+
116
114
#if TARGET_STM32F1
117
115
RtcHandle .Init .AsynchPrediv = RTC_AUTO_1_SECOND ;
118
116
#else /* TARGET_STM32F1 */
@@ -125,24 +123,14 @@ void rtc_init(void)
125
123
#endif /* TARGET_STM32F1 */
126
124
127
125
if (HAL_RTC_Init (& RtcHandle ) != HAL_OK ) {
128
- error ("RTC error: RTC initialization failed. " );
126
+ error ("RTC initialization failed" );
129
127
}
130
128
131
- #if DEVICE_LOWPOWERTIMER
129
+ rtc_synchronize (); // Wait for RSF
132
130
133
- #if !RTC_LSI
134
- if (!rtc_isenabled ())
135
- #endif /* !RTC_LSI */
136
- {
131
+ if (!rtc_isenabled ()) {
137
132
rtc_write (0 );
138
133
}
139
-
140
- NVIC_ClearPendingIRQ (RTC_WKUP_IRQn );
141
- NVIC_DisableIRQ (RTC_WKUP_IRQn );
142
- NVIC_SetVector (RTC_WKUP_IRQn , (uint32_t )RTC_IRQHandler );
143
- NVIC_EnableIRQ (RTC_WKUP_IRQn );
144
-
145
- #endif /* DEVICE_LOWPOWERTIMER */
146
134
}
147
135
148
136
void rtc_free (void )
@@ -279,8 +267,12 @@ void rtc_write(time_t t)
279
267
#endif /* TARGET_STM32F1 */
280
268
281
269
// Change the RTC current date/time
282
- HAL_RTC_SetDate (& RtcHandle , & dateStruct , RTC_FORMAT_BIN );
283
- HAL_RTC_SetTime (& RtcHandle , & timeStruct , RTC_FORMAT_BIN );
270
+ if (HAL_RTC_SetDate (& RtcHandle , & dateStruct , RTC_FORMAT_BIN ) != HAL_OK ) {
271
+ printf ("HAL_RTC_SetDate error\n" );
272
+ }
273
+ if (HAL_RTC_SetTime (& RtcHandle , & timeStruct , RTC_FORMAT_BIN ) != HAL_OK ) {
274
+ printf ("HAL_RTC_SetTime error\n" );
275
+ }
284
276
}
285
277
286
278
int rtc_isenabled (void )
@@ -292,6 +284,13 @@ int rtc_isenabled(void)
292
284
#endif /* TARGET_STM32F1 */
293
285
}
294
286
287
+ void rtc_synchronize (void )
288
+ {
289
+ if (HAL_RTC_WaitForSynchro (& RtcHandle ) != HAL_OK ) {
290
+ error ("rtc_synchronize error\n" );
291
+ }
292
+ }
293
+
295
294
#if DEVICE_LOWPOWERTIMER
296
295
297
296
static void RTC_IRQHandler (void )
@@ -304,23 +303,42 @@ static void RTC_IRQHandler(void)
304
303
}
305
304
}
306
305
307
- void rtc_set_irq_handler (uint32_t handler )
308
- {
309
- irq_handler = (void (* )(void ))handler ;
310
- }
311
-
312
306
uint32_t rtc_read_subseconds (void )
313
307
{
314
308
return 1000000.f * ((double )(RTC_SYNCH_PREDIV - RTC -> SSR ) / (RTC_SYNCH_PREDIV + 1 ));
315
309
}
316
310
317
311
void rtc_set_wake_up_timer (uint32_t delta )
318
312
{
319
- uint32_t wake_up_counter = delta / (2000000 / RTC_CLOCK );
313
+ /* Ex for Wakeup period resolution with RTCCLK=32768 Hz :
314
+ * RTCCLK_DIV2: ~122us < wakeup period < ~4s
315
+ * RTCCLK_DIV4: ~244us < wakeup period < ~8s
316
+ * RTCCLK_DIV8: ~488us < wakeup period < ~16s
317
+ * RTCCLK_DIV16: ~976us < wakeup period < ~32s
318
+ * CK_SPRE_16BITS: 1s < wakeup period < (0xFFFF+ 1) x 1 s = 65536 s (18 hours)
319
+ * CK_SPRE_17BITS: 18h+1s < wakeup period < (0x1FFFF+ 1) x 1 s = 131072 s (36 hours)
320
+ */
321
+ uint32_t WakeUpClock [6 ] = {RTC_WAKEUPCLOCK_RTCCLK_DIV2 , RTC_WAKEUPCLOCK_RTCCLK_DIV4 , RTC_WAKEUPCLOCK_RTCCLK_DIV8 , RTC_WAKEUPCLOCK_RTCCLK_DIV16 , RTC_WAKEUPCLOCK_CK_SPRE_16BITS , RTC_WAKEUPCLOCK_CK_SPRE_17BITS };
322
+ uint8_t ClockDiv [4 ] = {2 , 4 , 8 , 16 };
323
+ uint32_t WakeUpCounter ;
324
+ uint8_t DivIndex = 0 ;
325
+
326
+ do {
327
+ WakeUpCounter = delta / (ClockDiv [DivIndex ] * 1000000 / RTC_CLOCK );
328
+ DivIndex ++ ;
329
+ } while ( (WakeUpCounter > 0xFFFF ) && (DivIndex < 4 ) );
330
+
331
+ if (WakeUpCounter > 0xFFFF ) {
332
+ WakeUpCounter = delta / 1000000 ;
333
+ DivIndex ++ ;
334
+ }
320
335
321
- if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , wake_up_counter ,
322
- RTC_WAKEUPCLOCK_RTCCLK_DIV2 ) != HAL_OK ) {
323
- error ("Set wake up timer failed\n" );
336
+ irq_handler = (void (* )(void ))lp_ticker_irq_handler ;
337
+ NVIC_SetVector (RTC_WKUP_IRQn , (uint32_t )RTC_IRQHandler );
338
+ NVIC_EnableIRQ (RTC_WKUP_IRQn );
339
+
340
+ if (HAL_RTCEx_SetWakeUpTimer_IT (& RtcHandle , 0xFFFF & WakeUpCounter , WakeUpClock [DivIndex - 1 ]) != HAL_OK ) {
341
+ error ("rtc_set_wake_up_timer init error (%d)\n" , DivIndex );
324
342
}
325
343
}
326
344
@@ -329,10 +347,6 @@ void rtc_deactivate_wake_up_timer(void)
329
347
HAL_RTCEx_DeactivateWakeUpTimer (& RtcHandle );
330
348
}
331
349
332
- void rtc_synchronize (void )
333
- {
334
- HAL_RTC_WaitForSynchro (& RtcHandle );
335
- }
336
350
#endif /* DEVICE_LOWPOWERTIMER */
337
351
338
352
#endif /* DEVICE_RTC */
0 commit comments