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 14, 2023
1 parent 03140b6 commit 0385636
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 5 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 @@ -136,6 +137,26 @@ void STM32RTC::setClockSource(Source_Clock source, uint32_t predivA, uint32_t pr
RTC_setPrediv(predivA, predivS);
}

/**
* @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 @@ -130,6 +136,9 @@ class STM32RTC {
void getPrediv(uint32_t *predivA, uint32_t *predivS);
void setPrediv(uint32_t predivA, uint32_t predivS);

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 @@ -227,14 +236,15 @@ class STM32RTC {
friend class STM32LowPower;

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

static bool _timeSet;

Hour_Format _format;
Binary_Mode _mode;
AM_PM _hoursPeriod;
uint8_t _hours;
uint8_t _minutes;
Expand Down
51 changes: 48 additions & 3 deletions src/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,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 @@ -334,17 +338,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,7 +396,7 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
#endif

initFormat = format;

initMode = mode;
/* Ensure all RtcHandle properly set */
RtcHandle.Instance = RTC;
#if defined(STM32F1xx)
Expand Down Expand Up @@ -409,7 +445,10 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
// 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 @@ -463,6 +502,9 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
// Init RTC clock
RTC_initClock(source);
RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv));
#if defined(RTC_BINARY_NONE)
RTC_BinaryConf(mode);
#endif /* RTC_BINARY_NONE */
HAL_RTC_Init(&RtcHandle);
// Restore config
RTC_SetTime(hours, minutes, seconds, subSeconds, period);
Expand All @@ -481,6 +523,9 @@ bool RTC_init(hourFormat_t format, sourceClock_t source, bool reset)
RTC_initClock(source);
// This initialize variables: predivAsync, predivSync and predivSync_bits
RTC_getPrediv(&(RtcHandle.Init.AsynchPrediv), &(RtcHandle.Init.SynchPrediv));
#if defined(RTC_BINARY_NONE)
RTC_BinaryConf(mode);
#endif /* RTC_BINARY_NONE */
#if defined(STM32F1xx)
memcpy(&RtcHandle.DateToUpdate, &BackupDate, 4);
/* Update date automatically by calling HAL_RTC_GetDate */
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 @@ -169,7 +175,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(bool reset_cb);
bool RTC_IsConfigured(void);

Expand Down

0 comments on commit 0385636

Please sign in to comment.