Skip to content

Commit 9d07ee5

Browse files
FRASTMfpistm
authored andcommitted
fix: harden prediv management vs clock config
prediv was not properly computed and some misalignment's could occur depending of the RTC state at init. Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
1 parent 9acf6f7 commit 9d07ee5

File tree

5 files changed

+174
-191
lines changed

5 files changed

+174
-191
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ _RTC clock source_
3434
* **`void setClockSource(Source_Clock source)`** : this function must be called before `begin()`.
3535

3636
_RTC Asynchronous and Synchronous prescaler_
37-
* **`void getPrediv(int8_t *predivA, int16_t *predivS)`** : get (a)synchronous prescaler values if set else computed ones for the current clock source.
38-
* **`void setPrediv(int8_t predivA, int16_t predivS)`** : set (a)synchronous prescaler values. This function must be called before `begin()`. Use -1 to reset value and use computed ones. Those values have to match the following conditions: **_1Hz = RTC CLK source / ((predivA + 1) * (predivS + 1))_**
37+
* **`void getPrediv(uint32_t *predivA, uint32_t *predivS)`** : get (a)synchronous prescaler values if set else computed ones for the current clock source.
38+
* **`void setPrediv(uint32_t predivA, uint32_t predivS)`** : set (a)synchronous prescaler values. This function must be called before `begin()`. Use `(PREDIVA_MAX + 1)` and `(PREDIVS_MAX +1)` to reset value and use computed ones. Those values have to match the following conditions: **_1Hz = RTC CLK source / ((predivA + 1) * (predivS + 1))_**
3939

4040
_SubSeconds management_
4141
* **`uint32_t getSubSeconds(void)`**

src/STM32RTC.cpp

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ void STM32RTC::begin(bool resetTime, Hour_Format format)
103103
*/
104104
void STM32RTC::end(void)
105105
{
106-
RTC_DeInit();
106+
RTC_DeInit(true);
107107
_timeSet = false;
108108
}
109109

@@ -131,60 +131,38 @@ void STM32RTC::setClockSource(Source_Clock source)
131131
}
132132
}
133133

134-
#if defined(STM32F1xx)
135-
/**
136-
* @brief get user asynchronous prescaler value for the current clock source.
137-
* @param predivA: pointer to the current Asynchronous prescaler value
138-
* @param dummy : not used (kept for compatibility reason)
139-
* @retval None
140-
*/
141-
void STM32RTC::getPrediv(uint32_t *predivA, int16_t *dummy)
142-
{
143-
UNUSED(dummy);
144-
RTC_getPrediv(predivA);
145-
}
146-
#else
147134
/**
148135
* @brief get user (a)synchronous prescaler values if set else computed
149136
* ones for the current clock source.
150137
* @param predivA: pointer to the current Asynchronous prescaler value
151-
* @param predivS: pointer to the current Synchronous prescaler value
138+
* @param predivS: pointer to the current Synchronous prescaler value,
139+
* not used for STM32F1xx series.
152140
* @retval None
153141
*/
154-
void STM32RTC::getPrediv(int8_t *predivA, int16_t *predivS)
142+
void STM32RTC::getPrediv(uint32_t *predivA, uint32_t *predivS)
155143
{
156-
if ((predivA != nullptr) && (predivS != nullptr)) {
144+
if ((predivA != nullptr)
145+
#if !defined(STM32F1xx)
146+
&& (predivS != nullptr)
147+
#endif /* STM32F1xx */
148+
) {
157149
RTC_getPrediv(predivA, predivS);
158150
}
159151
}
160-
#endif /* STM32F1xx */
161152

162-
#if defined(STM32F1xx)
163-
/**
164-
* @brief set user asynchronous prescalers value.
165-
* @note This method must be called before begin().
166-
* @param predivA: Asynchronous prescaler value. Reset value: RTC_AUTO_1_SECOND
167-
* @param dummy : not used (kept for compatibility reason)
168-
* @retval None
169-
*/
170-
void STM32RTC::setPrediv(uint32_t predivA, int16_t dummy)
171-
{
172-
UNUSED(dummy);
173-
RTC_setPrediv(predivA);
174-
}
175-
#else
176153
/**
177154
* @brief set user (a)synchronous prescalers value.
178155
* @note This method must be called before begin().
179-
* @param predivA: Asynchronous prescaler value. Reset value: -1
180-
* @param predivS: Synchronous prescaler value. Reset value: -1
156+
* @param predivA: Asynchronous prescaler value.
157+
* @note Reset value: RTC_AUTO_1_SECOND for STM32F1xx series, else (PREDIVA_MAX + 1)
158+
* @param predivS: Synchronous prescaler value.
159+
* @note Reset value: (PREDIVS_MAX + 1), not used for STM32F1xx series.
181160
* @retval None
182161
*/
183-
void STM32RTC::setPrediv(int8_t predivA, int16_t predivS)
162+
void STM32RTC::setPrediv(uint32_t predivA, uint32_t predivS)
184163
{
185164
RTC_setPrediv(predivA, predivS);
186165
}
187-
#endif /* STM32F1xx */
188166

189167
/**
190168
* @brief enable the RTC alarm.

src/STM32RTC.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,9 @@ class STM32RTC {
212212
void setAlarmEpoch(time_t ts, Alarm_Match match, Alarm name);
213213
void setAlarmEpoch(time_t ts, Alarm_Match match = MATCH_DHHMMSS, uint32_t subSeconds = 0, Alarm name = ALARM_A);
214214

215-
#if defined(STM32F1xx)
216-
void getPrediv(uint32_t *predivA, int16_t *dummy = nullptr);
217-
void setPrediv(uint32_t predivA, int16_t dummy = 0);
218-
#else
219-
void getPrediv(int8_t *predivA, int16_t *predivS);
220-
void setPrediv(int8_t predivA, int16_t predivS);
221-
#endif /* STM32F1xx */
215+
void getPrediv(uint32_t *predivA, uint32_t *predivS);
216+
void setPrediv(uint32_t predivA, uint32_t predivS);
217+
222218
bool isConfigured(void)
223219
{
224220
return RTC_IsConfigured();
@@ -232,7 +228,10 @@ class STM32RTC {
232228
friend class STM32LowPower;
233229

234230
private:
235-
STM32RTC(void): _clockSource(LSI_CLOCK) {}
231+
STM32RTC(void): _clockSource(LSI_CLOCK)
232+
{
233+
setClockSource(_clockSource);
234+
}
236235

237236
static bool _timeSet;
238237

0 commit comments

Comments
 (0)