@@ -53,17 +53,41 @@ static void *callbackUserData = NULL;
53
53
54
54
static sourceClock_t clkSrc = LSI_CLOCK ;
55
55
static uint8_t HSEDiv = 0 ;
56
- static int8_t AsynchPrediv = -1 ; // 1 to 127
57
- static int16_t SynchPrediv = -1 ; // 0 to 32767
56
+ #if !defined(STM32F1xx )
57
+ /* Custom user values */
58
+ static int8_t userPredivAsync = -1 ;
59
+ static int16_t userPredivSync = -1 ;
60
+ #endif /* !STM32F1xx */
58
61
59
62
static hourFormat_t initFormat = HOUR_FORMAT_12 ;
60
63
61
64
/* Private function prototypes -----------------------------------------------*/
62
- static void RTC_setClock (sourceClock_t source );
63
- static void RTC_getPrediv (uint32_t * asynch , uint32_t * synch );
65
+ static void RTC_initClock (sourceClock_t source );
66
+ #if !defined(STM32F1xx )
67
+ static void RTC_computePrediv (int8_t * asynch , int16_t * synch );
68
+ #endif /* !STM32F1xx */
64
69
65
70
/* Exported functions --------------------------------------------------------*/
66
71
72
+ /**
73
+ * @brief Set RTC clock source
74
+ * @param source: RTC clock source: LSE, LSI or HSE
75
+ * @retval None
76
+ */
77
+ void RTC_SetClockSource (sourceClock_t source )
78
+ {
79
+ switch (source ) {
80
+ case LSI_CLOCK :
81
+ case LSE_CLOCK :
82
+ case HSE_CLOCK :
83
+ clkSrc = source ;
84
+ break ;
85
+ default :
86
+ clkSrc = LSI_CLOCK ;
87
+ break ;
88
+ }
89
+ }
90
+
67
91
/**
68
92
* @brief RTC clock initialization
69
93
* This function configures the hardware resources used.
@@ -74,7 +98,7 @@ static void RTC_getPrediv(uint32_t *asynch, uint32_t *synch);
74
98
* the backup registers) and RCC_CSR register are set to their reset values.
75
99
* @retval None
76
100
*/
77
- static void RTC_setClock (sourceClock_t source )
101
+ static void RTC_initClock (sourceClock_t source )
78
102
{
79
103
RCC_OscInitTypeDef RCC_OscInitStruct ;
80
104
RCC_PeriphCLKInitTypeDef PeriphClkInit ;
@@ -181,41 +205,64 @@ static void RTC_setClock(sourceClock_t source)
181
205
}
182
206
183
207
/**
184
- * @brief RTC_setPrediv
185
- * Allow to user to set manually the prescaler values.
186
- * @param Asynch : asynchronous prescaler value in range 1 - 127
187
- * @param Synch : synchronous prescaler value in range 0 - 32767
208
+ * @brief set user (a)synchronous prescaler values.
209
+ * @note use -1 to reset value and use computed ones
210
+ * @param asynch : asynchronous prescaler value in range 0 - PREDIVA_MAX
211
+ * @param synch : synchronous prescaler value in range 0 - PREDIVS_MAX
188
212
* @retval None
189
213
*/
190
- void RTC_setPrediv (int8_t Asynch , int16_t Synch )
214
+ void RTC_setPrediv (int8_t asynch , int16_t synch )
191
215
{
192
- if ((Asynch >= 1 ) && (Synch >= 0 )) {
193
- AsynchPrediv = Asynch ;
194
- SynchPrediv = Synch ;
216
+ #if !defined(STM32F1xx )
217
+ if ((asynch >= -1 ) && (synch >= -1 )) {
218
+ userPredivAsync = asynch ;
219
+ userPredivSync = synch ;
195
220
}
221
+ #else
222
+ UNUSED (asynch );
223
+ UNUSED (synch );
224
+ #endif /* !STM32F1xx */
196
225
}
197
226
198
227
/**
199
- * @brief RTC_getPrediv
200
- * RTC prescalers are set to obtain the RTC clock to 1Hz. See AN4759 .
228
+ * @brief get user (a)synchronous prescaler values if set else computed ones
229
+ * for the current clock source .
201
230
* @param asynch: pointer where return asynchronous prescaler value.
202
231
* @param synch: pointer where return synchronous prescaler value.
203
232
* @retval None
204
233
*/
205
- static void RTC_getPrediv (uint32_t * asynch , uint32_t * synch )
234
+ void RTC_getPrediv (int8_t * asynch , int16_t * synch )
206
235
{
207
- uint32_t predivA ;
208
- uint32_t predivS ;
209
- uint32_t clk = 0 ;
210
-
211
- if ((asynch == NULL ) || (synch == NULL )) {
212
- return ;
236
+ #if !defined(STM32F1xx )
237
+ if ((userPredivAsync == -1 ) || (userPredivSync == -1 )) {
238
+ RTC_computePrediv (asynch , synch );
239
+ } else {
240
+ if ((asynch != NULL ) && (synch != NULL )) {
241
+ * asynch = userPredivAsync ;
242
+ * synch = userPredivSync ;
243
+ }
213
244
}
245
+ #else
246
+ UNUSED (asynch );
247
+ UNUSED (synch );
248
+ #endif /* !STM32F1xx */
249
+ }
250
+
251
+ #if !defined(STM32F1xx )
252
+ /**
253
+ * @brief Compute (a)synchronous prescaler
254
+ * RTC prescalers are compute to obtain the RTC clock to 1Hz. See AN4759.
255
+ * @param asynch: pointer where return asynchronous prescaler value.
256
+ * @param synch: pointer where return synchronous prescaler value.
257
+ * @retval None
258
+ */
259
+ static void RTC_computePrediv (int8_t * asynch , int16_t * synch )
260
+ {
261
+ uint32_t predivS = PREDIVS_MAX + 1 ;
262
+ uint32_t clk = 0 ;
214
263
215
264
// Get user predividers if manually configured
216
- if ((AsynchPrediv > 0 ) && (SynchPrediv > 0 )) {
217
- * asynch = AsynchPrediv ;
218
- * synch = SynchPrediv ;
265
+ if ((asynch == NULL ) || (synch == NULL )) {
219
266
return ;
220
267
}
221
268
@@ -232,18 +279,29 @@ static void RTC_getPrediv(uint32_t *asynch, uint32_t *synch)
232
279
Error_Handler ();
233
280
}
234
281
235
- // Get prescalers
236
- if (clk > 0 ) {
237
- for (predivA = 128 ; predivA > 1 ; predivA -- ) {
238
- predivS = clk / predivA ;
239
- if ((predivS <= 32768 ) && ((predivS * predivA ) == clk )) {
240
- * asynch = predivA - 1 ;
241
- * synch = predivS - 1 ;
242
- break ;
243
- }
244
- }
282
+ /* Find (a)synchronous prescalers to obtain the 1Hz calendar clock */
283
+ for (* asynch = PREDIVA_MAX ; * asynch >= 0 ; (* asynch )-- ) {
284
+ predivS = (clk / (* asynch + 1 )) - 1 ;
285
+
286
+ if (((predivS + 1 ) * (* asynch + 1 )) == clk )
287
+ break ;
288
+ }
289
+
290
+ /*
291
+ * Can't find a 1Hz, so give priority to RTC power consumption
292
+ * by choosing the higher possible value for predivA
293
+ */
294
+ if ((predivS > PREDIVS_MAX ) || (* asynch < 0 )) {
295
+ * asynch = PREDIVA_MAX ;
296
+ predivS = (clk / (* asynch + 1 )) - 1 ;
297
+ }
298
+
299
+ if (predivS > PREDIVS_MAX ) {
300
+ Error_Handler ();
245
301
}
302
+ * synch = (int16_t )predivS ;
246
303
}
304
+ #endif /* !STM32F1xx */
247
305
248
306
/**
249
307
* @brief RTC Initialization
@@ -256,8 +314,8 @@ void RTC_init(hourFormat_t format, sourceClock_t source)
256
314
{
257
315
initFormat = format ;
258
316
259
- // Set RTC clock
260
- RTC_setClock (source );
317
+ // Init RTC clock
318
+ RTC_initClock (source );
261
319
262
320
RtcHandle .Instance = RTC ;
263
321
@@ -272,7 +330,7 @@ void RTC_init(hourFormat_t format, sourceClock_t source)
272
330
RtcHandle .Init .HourFormat = RTC_HOURFORMAT_24 ;
273
331
}
274
332
RtcHandle .Init .OutPut = RTC_OUTPUT_DISABLE ;
275
- RTC_getPrediv (& (RtcHandle .Init .AsynchPrediv ), & (RtcHandle .Init .SynchPrediv ));
333
+ RTC_getPrediv (( int8_t * ) & (RtcHandle .Init .AsynchPrediv ), ( int16_t * ) & (RtcHandle .Init .SynchPrediv ));
276
334
#if defined(STM32L0xx ) || defined(STM32L4xx )
277
335
RtcHandle .Init .OutPutRemap = RTC_OUTPUT_REMAP_NONE ;
278
336
#endif // defined(STM32L0xx) || defined(STM32L4xx)
0 commit comments