Skip to content

Commit af876a0

Browse files
Clarify description of rtc_isenabled() and standardize behavior on CI targets (#518)
* Clarify description of rtc_isenabled() and standardize behavior on CI targets * Wording fix
1 parent b79911c commit af876a0

File tree

8 files changed

+79
-38
lines changed

8 files changed

+79
-38
lines changed

drivers/include/drivers/RealTimeClock.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,16 @@ class RealTimeClock {
7373
return rtc_free();
7474
}
7575

76-
/** Check if the RTC has the time set and is counting
76+
/** Check if the RTC has been initialized and is counting
7777
*
7878
* @retval false The time reported by the RTC is not valid
79-
* @retval true The time has been set and the RTC is counting
79+
* @retval true The RTC has been initialized and is counting
80+
*
81+
* @note In versions of Mbed before 7.0, this function claimed to return false "if the time had not been set."
82+
* However, this was flawed because, in most implementations, it only returned true if the time had been
83+
* set *on this boot*. There wasn't, and isn't, a way to detect whether the time was set correctly by a previous
84+
* boot. To answer that question, you may wish to check if the time is approximately valid (in the 21st
85+
* century), or add another flag at the application level.
8086
*
8187
* @see ::rtc_isenabled
8288
*/

hal/include/hal/rtc_api.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ extern "C" {
4444
* * Shutdown mode doesn't stop RTC from counting - Not verified.
4545
* * The functions ::rtc_write/::rtc_read provides availability to set/get RTC time
4646
* - Verified by test rtc_write_read_test.
47-
* * The functions ::rtc_isenabled returns 1 if the RTC is counting and the time has been set,
48-
* 0 otherwise - Verified by test rtc_enabled_test.
47+
* * The function ::rtc_isenabled returns 1 if the RTC has been initialized and is counting and 0 otherwise - Verified by test rtc_enabled_test.
4948
* * ::rtc_read may be called before rtc_write. If the RTC time has not been set, this will return the
5049
* time since some arbitrary epoch. If the RTC time was set on a previous boot, this will return time
5150
* based on what was set then.
@@ -115,13 +114,23 @@ void rtc_init(void);
115114
* POWER_CTRL &= ~POWER_CTRL_RTC_Msk;
116115
* }
117116
* @endcode
117+
*
118+
* @note Implementations are allowed to not implement this function if it's impossible or there is
119+
* no significant benefit to disabling the RTC. As such, the RTC is allowed to remain initialized
120+
* after this function is called if freeing the RTC is not implemented.
118121
*/
119122
void rtc_free(void);
120123

121-
/** Check if the RTC has the time set and is counting
124+
/** Check if the RTC has been initialized and is counting
122125
*
123126
* @retval 0 The time reported by the RTC is not valid
124-
* @retval 1 The time has been set the RTC is counting
127+
* @retval 1 The RTC has been initialized and is counting
128+
*
129+
* @note In versions of Mbed before 7.0, this function claimed to return false "if the time had not been set."
130+
* However, this was flawed because, in most implementations, it only returned true if the time had been
131+
* set *on this boot*. There wasn't, and isn't, a way to detect whether the time was set correctly by a previous
132+
* boot. To answer that question, you may wish to check if the time is approximately valid (in the 21st
133+
* century), or add another flag at the application level.
125134
*
126135
* Example Implementation Pseudo Code:
127136
* @code

hal/tests/TESTS/mbed_hal/rtc_reset/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ if(NOT "DEVICE_RTC=1" IN_LIST MBED_TARGET_DEFINITIONS)
55
set(TEST_SKIPPED "RTC is not supported for this target")
66
endif()
77

8+
if(NOT "TARGET_K64F" IN_LIST MBED_TARGET_DEFINITIONS)
9+
# Currently this test works OK, but causes the next 5-10 programming operations with OpenOCD to fail
10+
set(TEST_SKIPPED "This test causes issues with this target's debug interface")
11+
endif()
12+
813
mbed_greentea_add_test(
914
TEST_NAME
1015
mbed-hal-rtc-reset

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/rtc_api.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,31 @@
2222
#include "fsl_rtc.h"
2323
#include "PeripheralPins.h"
2424

25-
static bool rtc_time_set = false;
25+
static bool rtc_enabled = false;
2626

2727
void rtc_init(void)
2828
{
2929
rtc_config_t rtcConfig;
3030

31-
RTC_GetDefaultConfig(&rtcConfig);
32-
RTC_Init(RTC, &rtcConfig);
31+
if (!rtc_enabled) {
32+
RTC_GetDefaultConfig(&rtcConfig);
33+
RTC_Init(RTC, &rtcConfig);
3334

34-
RTC_StartTimer(RTC);
35+
RTC_StartTimer(RTC);
36+
}
37+
38+
rtc_enabled = true;
3539
}
3640

3741
void rtc_free(void)
3842
{
43+
if (rtc_enabled) {
3944
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
40-
/* Gate the module clock */
41-
CLOCK_DisableClock(kCLOCK_Rtc0);
45+
/* Gate the module clock */
46+
CLOCK_DisableClock(kCLOCK_Rtc0);
4247
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
48+
rtc_enabled = false;
49+
}
4350
}
4451

4552
/*
@@ -48,18 +55,7 @@ void rtc_free(void)
4855
*/
4956
int rtc_isenabled(void)
5057
{
51-
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
52-
CLOCK_EnableClock(kCLOCK_Rtc0);
53-
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
54-
55-
const bool rtc_init_done = ((RTC->SR & RTC_SR_TCE_MASK) >> RTC_SR_TCE_SHIFT);
56-
57-
/* If RTC is not initialized, then disable the clock gate on exit. */
58-
if(!rtc_init_done) {
59-
rtc_free();
60-
}
61-
62-
return (rtc_init_done & rtc_time_set);
58+
return rtc_enabled;
6359
}
6460

6561
time_t rtc_read(void)
@@ -72,8 +68,6 @@ void rtc_write(time_t t)
7268
RTC_StopTimer(RTC);
7369
RTC->TSR = t;
7470
RTC_StartTimer(RTC);
75-
76-
rtc_time_set = true;
7771
}
7872

7973
#endif

targets/TARGET_NXP/TARGET_LPC17XX/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ target_sources(mbed-lpc17xx
3939
spi_api.c
4040
us_ticker.c
4141
watchdog_api.c
42+
mbed_overrides.c
4243

4344
device/CRP.c
4445
device/flash_api.c
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2025 Jamie Smith
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include <rtc_api.h>
19+
20+
void mbed_sdk_init(void)
21+
{
22+
// RTC register block is on at boot, so turn it off until we need it (this is also needed to pass RTC tests).
23+
rtc_free();
24+
}

targets/TARGET_NXP/TARGET_LPC17XX/rtc_api.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#include "rtc_api.h"
1818
#include "mbed_mktime.h"
1919

20-
// ensure rtc is running (unchanged if already running)
20+
// RTC Power/Clock Control bit
21+
#define LPC_SC_PCONP_PCRTC (1 << 9)
2122

2223
/* Setup the RTC based on a time structure, ensuring RTC is enabled
2324
*
@@ -36,14 +37,19 @@
3637
* without impacting if it is the case
3738
*/
3839
void rtc_init(void) {
39-
LPC_SC->PCONP |= 0x200; // Ensure power is on
40-
LPC_RTC->CCR = 0x00;
41-
42-
LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
40+
if(!rtc_isenabled()) {
41+
LPC_SC->PCONP |= LPC_SC_PCONP_PCRTC; // Ensure power is on
42+
LPC_RTC->CCR = 0x00;
43+
44+
LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
45+
}
4346
}
4447

4548
void rtc_free(void) {
46-
// [TODO]
49+
// Turn off power for RTC register block.
50+
// The datasheet is not very clear, but in my testing, this does not impact the ability of the RTC
51+
// to count the time.
52+
LPC_SC->PCONP &= ~LPC_SC_PCONP_PCRTC;
4753
}
4854

4955
/*
@@ -54,7 +60,7 @@ void rtc_free(void) {
5460
*
5561
*/
5662
int rtc_isenabled(void) {
57-
return(((LPC_RTC->CCR) & 0x01) != 0);
63+
return (LPC_SC->PCONP & LPC_SC_PCONP_PCRTC) && (LPC_RTC->CCR & 0x01);
5864
}
5965

6066
/*

targets/TARGET_STM/rtc_api.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,7 @@ void rtc_write(time_t t)
294294

295295
int rtc_isenabled(void)
296296
{
297-
#if defined (RTC_FLAG_INITS) /* all STM32 except STM32F1 */
298-
return LL_RTC_IsActiveFlag_INITS(RTC);
299-
#else /* RTC_FLAG_INITS */ /* TARGET_STM32F1 */
300-
return ((RTC->CRL & RTC_CRL_RSF) == RTC_CRL_RSF);
301-
#endif /* RTC_FLAG_INITS */
297+
return RTC_inited;
302298
}
303299

304300

0 commit comments

Comments
 (0)