Skip to content

Commit

Permalink
fix: harden prediv management vs clock config
Browse files Browse the repository at this point in the history
prediv was not properly computed and some misalignment's
could occur depending of the RTC state at init.

Signed-off-by: Frederic Pillon <[email protected]>
  • Loading branch information
FRASTM authored and fpistm committed Sep 8, 2023
1 parent 2bacacb commit d4b14e6
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 158 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ _RTC clock source_
* **`void setClockSource(Source_Clock source)`** : this function must be called before `begin()`.

_RTC Asynchronous and Synchronous prescaler_
* **`void getPrediv(int8_t *predivA, int16_t *predivS)`** : get (a)synchronous prescaler values if set else computed ones for the current clock source.
* **`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))_**
* **`void getPrediv(uint32_t *predivA, uint32_t *predivS)`** : get (a)synchronous prescaler values if set else computed ones for the current clock source.
* **`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))_**

_SubSeconds management_
* **`uint32_t getSubSeconds(void)`**
Expand Down
52 changes: 19 additions & 33 deletions src/STM32RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,60 +131,46 @@ void STM32RTC::setClockSource(Source_Clock source)
}
}

#if defined(STM32F1xx)
/**
* @brief get user asynchronous prescaler value for the current clock source.
* @param predivA: pointer to the current Asynchronous prescaler value
* @param dummy : not used (kept for compatibility reason)
* @retval None
*/
void STM32RTC::getPrediv(uint32_t *predivA, int16_t *dummy)
{
UNUSED(dummy);
RTC_getPrediv(predivA);
}
#else
/**
* @brief get user (a)synchronous prescaler values if set else computed
* ones for the current clock source.
* @param predivA: pointer to the current Asynchronous prescaler value
* @param predivS: pointer to the current Synchronous prescaler value
* @param predivS: pointer to the current Synchronous prescaler value,
* not used for STM32F1xx series.
* @retval None
*/
void STM32RTC::getPrediv(int8_t *predivA, int16_t *predivS)
void STM32RTC::getPrediv(uint32_t *predivA, uint32_t *predivS)
{
#if defined(STM32F1xx)
UNUSED(predivS);
if (predivA != nullptr) {
RTC_getPrediv(predivA);
}
#else
if ((predivA != nullptr) && (predivS != nullptr)) {
RTC_getPrediv(predivA, predivS);
}
}
#endif /* STM32F1xx */
}

#if defined(STM32F1xx)
/**
* @brief set user asynchronous prescalers value.
* @brief set user (a)synchronous prescalers value.
* @note This method must be called before begin().
* @param predivA: Asynchronous prescaler value. Reset value: RTC_AUTO_1_SECOND
* @param dummy : not used (kept for compatibility reason)
* @param predivA: Asynchronous prescaler value.
* @note Reset value: RTC_AUTO_1_SECOND for STM32F1xx series, else (PREDIVA_MAX + 1)
* @param predivS: Synchronous prescaler value.
* @note Reset value: (PREDIVS_MAX + 1), not used for STM32F1xx series.
* @retval None
*/
void STM32RTC::setPrediv(uint32_t predivA, int16_t dummy)
void STM32RTC::setPrediv(uint32_t predivA, uint32_t predivS)
{
UNUSED(dummy);
#if defined(STM32F1xx)
UNUSED(predivS);
RTC_setPrediv(predivA);
}
#else
/**
* @brief set user (a)synchronous prescalers value.
* @note This method must be called before begin().
* @param predivA: Asynchronous prescaler value. Reset value: -1
* @param predivS: Synchronous prescaler value. Reset value: -1
* @retval None
*/
void STM32RTC::setPrediv(int8_t predivA, int16_t predivS)
{
RTC_setPrediv(predivA, predivS);
}
#endif /* STM32F1xx */
}

/**
* @brief enable the RTC alarm.
Expand Down
10 changes: 3 additions & 7 deletions src/STM32RTC.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,9 @@ class STM32RTC {
void setAlarmEpoch(time_t ts, Alarm_Match match, Alarm name);
void setAlarmEpoch(time_t ts, Alarm_Match match = MATCH_DHHMMSS, uint32_t subSeconds = 0, Alarm name = ALARM_A);

#if defined(STM32F1xx)
void getPrediv(uint32_t *predivA, int16_t *dummy = nullptr);
void setPrediv(uint32_t predivA, int16_t dummy = 0);
#else
void getPrediv(int8_t *predivA, int16_t *predivS);
void setPrediv(int8_t predivA, int16_t predivS);
#endif /* STM32F1xx */
void getPrediv(uint32_t *predivA, uint32_t *predivS);
void setPrediv(uint32_t predivA, uint32_t predivS);

bool isConfigured(void)
{
return RTC_IsConfigured();
Expand Down
Loading

0 comments on commit d4b14e6

Please sign in to comment.