Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions drivers/include/drivers/RealTimeClock.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,16 @@ class RealTimeClock {
return rtc_free();
}

/** Check if the RTC has the time set and is counting
/** Check if the RTC has been initialized and is counting
*
* @retval false The time reported by the RTC is not valid
* @retval true The time has been set and the RTC is counting
* @retval true The RTC has been initialized and is counting
*
* @note In versions of Mbed before 7.0, this function claimed to return false "if the time had not been set."
* However, this was flawed because, in most implementations, it only returned true if the time had been
* set *on this boot*. There wasn't, and isn't, a way to detect whether the time was set correctly by a previous
* boot. To answer that question, you may wish to check if the time is approximately valid (in the 21st
* century), or add another flag at the application level.
*
* @see ::rtc_isenabled
*/
Expand Down
17 changes: 13 additions & 4 deletions hal/include/hal/rtc_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ extern "C" {
* * Shutdown mode doesn't stop RTC from counting - Not verified.
* * The functions ::rtc_write/::rtc_read provides availability to set/get RTC time
* - Verified by test rtc_write_read_test.
* * The functions ::rtc_isenabled returns 1 if the RTC is counting and the time has been set,
* 0 otherwise - Verified by test rtc_enabled_test.
* * The function ::rtc_isenabled returns 1 if the RTC has been initialized and 0 otherwise - Verified by test rtc_enabled_test.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defined behaviour says: “returns 1 if the RTC has been initialized and 0 otherwise.”
Function says: “retval 1 The RTC has been initialized and is counting.

* * ::rtc_read may be called before rtc_write. If the RTC time has not been set, this will return the
* time since some arbitrary epoch. If the RTC time was set on a previous boot, this will return time
* based on what was set then.
Expand Down Expand Up @@ -115,13 +114,23 @@ void rtc_init(void);
* POWER_CTRL &= ~POWER_CTRL_RTC_Msk;
* }
* @endcode
*
* @note Implementations are allowed to not implement this function if it's impossible or there is
* no significant benefit to disabling the RTC. As such, the RTC is allowed to remain initialized
* after this function is called if freeing the RTC is not implemented.
*/
void rtc_free(void);

/** Check if the RTC has the time set and is counting
/** Check if the RTC has been initialized and is counting
*
* @retval 0 The time reported by the RTC is not valid
* @retval 1 The time has been set the RTC is counting
* @retval 1 The RTC has been initialized and is counting
*
* @note In versions of Mbed before 7.0, this function claimed to return false "if the time had not been set."
* However, this was flawed because, in most implementations, it only returned true if the time had been
* set *on this boot*. There wasn't, and isn't, a way to detect whether the time was set correctly by a previous
* boot. To answer that question, you may wish to check if the time is approximately valid (in the 21st
* century), or add another flag at the application level.
*
* Example Implementation Pseudo Code:
* @code
Expand Down
5 changes: 5 additions & 0 deletions hal/tests/TESTS/mbed_hal/rtc_reset/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ if(NOT "DEVICE_RTC=1" IN_LIST MBED_TARGET_DEFINITIONS)
set(TEST_SKIPPED "RTC is not supported for this target")
endif()

if(NOT "TARGET_K64F" IN_LIST MBED_TARGET_DEFINITIONS)
# Currently this test works OK, but causes the next 5-10 programming operations with OpenOCD to fail
set(TEST_SKIPPED "This test causes issues with this target's debug interface")
endif()

mbed_greentea_add_test(
TEST_NAME
mbed-hal-rtc-reset
Expand Down
34 changes: 14 additions & 20 deletions targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/rtc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,31 @@
#include "fsl_rtc.h"
#include "PeripheralPins.h"

static bool rtc_time_set = false;
static bool rtc_enabled = false;

void rtc_init(void)
{
rtc_config_t rtcConfig;

RTC_GetDefaultConfig(&rtcConfig);
RTC_Init(RTC, &rtcConfig);
if (!rtc_enabled) {
RTC_GetDefaultConfig(&rtcConfig);
RTC_Init(RTC, &rtcConfig);

RTC_StartTimer(RTC);
RTC_StartTimer(RTC);
}

rtc_enabled = true;
}

void rtc_free(void)
{
if (rtc_enabled) {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate the module clock */
CLOCK_DisableClock(kCLOCK_Rtc0);
/* Gate the module clock */
CLOCK_DisableClock(kCLOCK_Rtc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
rtc_enabled = false;
}
}

/*
Expand All @@ -48,18 +55,7 @@ void rtc_free(void)
*/
int rtc_isenabled(void)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Rtc0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

const bool rtc_init_done = ((RTC->SR & RTC_SR_TCE_MASK) >> RTC_SR_TCE_SHIFT);

/* If RTC is not initialized, then disable the clock gate on exit. */
if(!rtc_init_done) {
rtc_free();
}

return (rtc_init_done & rtc_time_set);
return rtc_enabled;
}

time_t rtc_read(void)
Expand All @@ -72,8 +68,6 @@ void rtc_write(time_t t)
RTC_StopTimer(RTC);
RTC->TSR = t;
RTC_StartTimer(RTC);

rtc_time_set = true;
}

#endif
1 change: 1 addition & 0 deletions targets/TARGET_NXP/TARGET_LPC17XX/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ target_sources(mbed-lpc17xx
spi_api.c
us_ticker.c
watchdog_api.c
mbed_overrides.c

device/CRP.c
device/flash_api.c
Expand Down
24 changes: 24 additions & 0 deletions targets/TARGET_NXP/TARGET_LPC17XX/mbed_overrides.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* mbed Microcontroller Library
* Copyright (c) 2025 Jamie Smith
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <rtc_api.h>

void mbed_sdk_init(void)
{
// RTC register block is on at boot, so turn it off until we need it (this is also needed to pass RTC tests).
rtc_free();
}
20 changes: 13 additions & 7 deletions targets/TARGET_NXP/TARGET_LPC17XX/rtc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#include "rtc_api.h"
#include "mbed_mktime.h"

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

/* Setup the RTC based on a time structure, ensuring RTC is enabled
*
Expand All @@ -36,14 +37,19 @@
* without impacting if it is the case
*/
void rtc_init(void) {
LPC_SC->PCONP |= 0x200; // Ensure power is on
LPC_RTC->CCR = 0x00;

LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
if(!rtc_isenabled()) {
LPC_SC->PCONP |= LPC_SC_PCONP_PCRTC; // Ensure power is on
LPC_RTC->CCR = 0x00;

LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
}
}

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

/*
Expand All @@ -54,7 +60,7 @@ void rtc_free(void) {
*
*/
int rtc_isenabled(void) {
return(((LPC_RTC->CCR) & 0x01) != 0);
return (LPC_SC->PCONP & LPC_SC_PCONP_PCRTC) && (LPC_RTC->CCR & 0x01);
}

/*
Expand Down
6 changes: 1 addition & 5 deletions targets/TARGET_STM/rtc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,7 @@ void rtc_write(time_t t)

int rtc_isenabled(void)
{
#if defined (RTC_FLAG_INITS) /* all STM32 except STM32F1 */
return LL_RTC_IsActiveFlag_INITS(RTC);
#else /* RTC_FLAG_INITS */ /* TARGET_STM32F1 */
return ((RTC->CRL & RTC_CRL_RSF) == RTC_CRL_RSF);
#endif /* RTC_FLAG_INITS */
return RTC_inited;
}


Expand Down