Skip to content

Commit

Permalink
feat: add a parameter to set binary mode
Browse files Browse the repository at this point in the history
This is valid when the RTC_BINARY_MIX mode exists in the RTC
(bitfield in the RTC ICSR register)
Set the RTC mode through a setBinaryMode function to be called
before begin.

Signed-off-by: Francois Ramu <[email protected]>
Co-authored-by: Frederic Pillon <[email protected]>
  • Loading branch information
fpistm committed Sep 8, 2023
1 parent d4b14e6 commit feca5ec
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 7 deletions.
21 changes: 21 additions & 0 deletions src/STM32RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void STM32RTC::begin(bool resetTime, Hour_Format format)

_format = format;
reinit = RTC_init((format == HOUR_12) ? HOUR_FORMAT_12 : HOUR_FORMAT_24,
(_mode == MODE_MIX) ? ::MODE_BINARY_MIX : ((_mode == MODE_BIN) ? ::MODE_BINARY_ONLY : ::MODE_BINARY_NONE),
(_clockSource == LSE_CLOCK) ? ::LSE_CLOCK :
(_clockSource == HSE_CLOCK) ? ::HSE_CLOCK : ::LSI_CLOCK
, resetTime);
Expand Down Expand Up @@ -131,6 +132,26 @@ void STM32RTC::setClockSource(Source_Clock source)
}
}

/**
* @brief get the Binary Mode.
* @retval mode: MODE_BCD, MODE_BIN or MODE_MIX
*/
STM32RTC::Binary_Mode STM32RTC::getBinaryMode(void)
{
return _mode;
}

/**
* @brief set the Binary Mode. By default MODE_BCD is selected. This
* method must be called before begin().
* @param mode: the RTC mode: MODE_BCD, MODE_BIN or MODE_MIX
* @retval None
*/
void STM32RTC::setBinaryMode(Binary_Mode mode)
{
_mode = mode;
}

/**
* @brief get user (a)synchronous prescaler values if set else computed
* ones for the current clock source.
Expand Down
12 changes: 11 additions & 1 deletion src/STM32RTC.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ class STM32RTC {
PM = HOUR_PM
};

enum Binary_Mode : uint8_t {
MODE_BCD = MODE_BINARY_NONE, /* not used */
MODE_BIN = MODE_BINARY_ONLY,
MODE_MIX = MODE_BINARY_MIX
};

enum Alarm_Match : uint8_t {
MATCH_OFF = OFF_MSK, // Never
MATCH_SS = SS_MSK, // Every Minute
Expand Down Expand Up @@ -128,6 +134,9 @@ class STM32RTC {
Source_Clock getClockSource(void);
void setClockSource(Source_Clock source);

Binary_Mode getBinaryMode(void);
void setBinaryMode(Binary_Mode mode);

void enableAlarm(Alarm_Match match, Alarm name = ALARM_A);
void disableAlarm(Alarm name = ALARM_A);

Expand Down Expand Up @@ -228,11 +237,12 @@ class STM32RTC {
friend class STM32LowPower;

private:
STM32RTC(void): _clockSource(LSI_CLOCK) {}
STM32RTC(void): _mode(MODE_BCD), _clockSource(LSI_CLOCK) {}

static bool _timeSet;

Hour_Format _format;
Binary_Mode _mode;
AM_PM _hoursPeriod;
uint8_t _hours;
uint8_t _minutes;
Expand Down
50 changes: 45 additions & 5 deletions src/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,16 @@ static uint32_t prediv = RTC_AUTO_1_SECOND;
#endif /* !STM32F1xx */

static hourFormat_t initFormat = HOUR_FORMAT_12;
static binaryMode_t initMode = MODE_BINARY_NONE;

/* Private function prototypes -----------------------------------------------*/
static void RTC_initClock(sourceClock_t source);
#if !defined(STM32F1xx)
static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch);
#endif /* !STM32F1xx */
#if defined(RTC_BINARY_NONE)
static void RTC_BinaryConf(binaryMode_t mode);
#endif

static inline int _log2(int x)
{
Expand Down Expand Up @@ -332,17 +336,49 @@ static void RTC_computePrediv(uint32_t *asynch, uint32_t *synch)
}
#endif /* !STM32F1xx */

#if defined(RTC_BINARY_NONE)
static void RTC_BinaryConf(binaryMode_t mode)
{
RtcHandle.Init.BinMode = (mode == MODE_BINARY_MIX) ? RTC_BINARY_MIX : ((mode == MODE_BINARY_ONLY) ? RTC_BINARY_ONLY : RTC_BINARY_NONE);
if (RtcHandle.Init.BinMode == RTC_BINARY_MIX) {
/* Configure the 1s BCD calendar increment */

uint32_t inc = 1 / (1.0 / ((float)clkVal / (float)(predivAsync + 1.0)));
if (inc <= 256) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_0;
} else if (inc < (256 << 1)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_1;
} else if (inc < (256 << 2)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_2;
} else if (inc < (256 << 3)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_3;
} else if (inc < (256 << 4)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_4;
} else if (inc < (256 << 5)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_5;
} else if (inc < (256 << 6)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_6;
} else if (inc < (256 << 7)) {
RtcHandle.Init.BinMixBcdU = RTC_BINARY_MIX_BCDU_7;
} else {
Error_Handler();
}
}
}
#endif /* RTC_BINARY_NONE */

/**
* @brief RTC Initialization
* This function configures the RTC time and calendar. By default, the
* RTC is set to the 1st January 2001
* Note: year 2000 is invalid as it is the hardware reset value and doesn't raise INITS flag
* @param format: enable the RTC in 12 or 24 hours mode
* @param mode: enable the RTC in BCD or Mix or Binary mode
* @param source: RTC clock source: LSE, LSI or HSE
* @param reset: force RTC reset, even if previously configured
* @retval True if RTC is reinitialized, else false
*/
bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool reset)
{
bool reinit = false;
hourAM_PM_t period = HOUR_AM, alarmPeriod = HOUR_AM;
Expand All @@ -360,6 +396,7 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
uint32_t sync;

initFormat = format;
initMode = mode;
RtcHandle.Instance = RTC;

/* Ensure backup domain is enabled before we init the RTC so we can use the backup registers for date retention on stm32f1xx boards */
Expand Down Expand Up @@ -402,13 +439,13 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
#if defined(RTC_OUTPUT_REMAP_NONE)
RtcHandle.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
#endif /* RTC_OUTPUT_REMAP_NONE */
#if defined(RTC_BINARY_NONE)
RtcHandle.Init.BinMode = RTC_BINARY_NONE;
#endif
// Init RTC clock
RTC_initClock(source);
RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv));
#endif // STM32F1xx
#if defined(RTC_BINARY_NONE)
RTC_BinaryConf(mode);
#endif /* RTC_BINARY_NONE */
#endif // STM32F1xx

HAL_RTC_Init(&RtcHandle);
// Default: saturday 1st of January 2001
Expand Down Expand Up @@ -487,6 +524,9 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
RTC_SetDate(RtcHandle.DateToUpdate.Year, RtcHandle.DateToUpdate.Month,
RtcHandle.DateToUpdate.Date, RtcHandle.DateToUpdate.WeekDay);
#endif // STM32F1xx
#if defined(RTC_BINARY_NONE)
RTC_BinaryConf(mode);
#endif /* RTC_BINARY_NONE */
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ typedef enum {
HOUR_FORMAT_24
} hourFormat_t;

typedef enum {
MODE_BINARY_NONE, /* BCD only */
MODE_BINARY_ONLY,
MODE_BINARY_MIX
} binaryMode_t;

typedef enum {
HOUR_AM,
HOUR_PM
Expand Down Expand Up @@ -168,7 +174,7 @@ void RTC_SetClockSource(sourceClock_t source);
void RTC_getPrediv(uint32_t *asynch, uint32_t *synch);
void RTC_setPrediv(uint32_t asynch, uint32_t synch);

bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset);
bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool reset);
void RTC_DeInit(void);
bool RTC_IsConfigured(void);

Expand Down

0 comments on commit feca5ec

Please sign in to comment.