@@ -53,17 +53,41 @@ static void *callbackUserData = NULL;
5353
5454static sourceClock_t clkSrc = LSI_CLOCK ;
5555static 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 */
5861
5962static hourFormat_t initFormat = HOUR_FORMAT_12 ;
6063
6164/* 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 */
6469
6570/* Exported functions --------------------------------------------------------*/
6671
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+
6791/**
6892 * @brief RTC clock initialization
6993 * This function configures the hardware resources used.
@@ -74,7 +98,7 @@ static void RTC_getPrediv(uint32_t *asynch, uint32_t *synch);
7498 * the backup registers) and RCC_CSR register are set to their reset values.
7599 * @retval None
76100 */
77- static void RTC_setClock (sourceClock_t source )
101+ static void RTC_initClock (sourceClock_t source )
78102{
79103 RCC_OscInitTypeDef RCC_OscInitStruct ;
80104 RCC_PeriphCLKInitTypeDef PeriphClkInit ;
@@ -181,41 +205,64 @@ static void RTC_setClock(sourceClock_t source)
181205}
182206
183207/**
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
188212 * @retval None
189213 */
190- void RTC_setPrediv (int8_t Asynch , int16_t Synch )
214+ void RTC_setPrediv (int8_t asynch , int16_t synch )
191215{
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 ;
195220 }
221+ #else
222+ UNUSED (asynch );
223+ UNUSED (synch );
224+ #endif /* !STM32F1xx */
196225}
197226
198227/**
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 .
201230 * @param asynch: pointer where return asynchronous prescaler value.
202231 * @param synch: pointer where return synchronous prescaler value.
203232 * @retval None
204233 */
205- static void RTC_getPrediv (uint32_t * asynch , uint32_t * synch )
234+ void RTC_getPrediv (int8_t * asynch , int16_t * synch )
206235{
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+ }
213244 }
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 ;
214263
215264 // Get user predividers if manually configured
216- if ((AsynchPrediv > 0 ) && (SynchPrediv > 0 )) {
217- * asynch = AsynchPrediv ;
218- * synch = SynchPrediv ;
265+ if ((asynch == NULL ) || (synch == NULL )) {
219266 return ;
220267 }
221268
@@ -232,18 +279,29 @@ static void RTC_getPrediv(uint32_t *asynch, uint32_t *synch)
232279 Error_Handler ();
233280 }
234281
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 ();
245301 }
302+ * synch = (int16_t )predivS ;
246303}
304+ #endif /* !STM32F1xx */
247305
248306/**
249307 * @brief RTC Initialization
@@ -256,8 +314,8 @@ void RTC_init(hourFormat_t format, sourceClock_t source)
256314{
257315 initFormat = format ;
258316
259- // Set RTC clock
260- RTC_setClock (source );
317+ // Init RTC clock
318+ RTC_initClock (source );
261319
262320 RtcHandle .Instance = RTC ;
263321
@@ -272,7 +330,7 @@ void RTC_init(hourFormat_t format, sourceClock_t source)
272330 RtcHandle .Init .HourFormat = RTC_HOURFORMAT_24 ;
273331 }
274332 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 ));
276334#if defined(STM32L0xx ) || defined(STM32L4xx )
277335 RtcHandle .Init .OutPutRemap = RTC_OUTPUT_REMAP_NONE ;
278336#endif // defined(STM32L0xx) || defined(STM32L4xx)
0 commit comments