diff --git a/arch/arm/src/rp23xx/CMakeLists.txt b/arch/arm/src/rp23xx/CMakeLists.txt index 84c46b22374..4fd9afd4055 100644 --- a/arch/arm/src/rp23xx/CMakeLists.txt +++ b/arch/arm/src/rp23xx/CMakeLists.txt @@ -110,6 +110,9 @@ endif() if(CONFIG_RP23XX_RTC) list(APPEND SRCS rp23xx_rtc.c) + if(CONFIG_RTC_DRIVER) + list(APPEND SRCS rp23xx_rtc_lowerhalf.c) + endif() endif() if(CONFIG_RP23XX_OTP) diff --git a/arch/arm/src/rp23xx/Kconfig b/arch/arm/src/rp23xx/Kconfig index 39c79b3d08d..7c3e4180c53 100644 --- a/arch/arm/src/rp23xx/Kconfig +++ b/arch/arm/src/rp23xx/Kconfig @@ -878,6 +878,9 @@ config RP23XX_RTC timer is a 64-bit millisecond counter clocked from the low-power oscillator, so it keeps running across warm resets. + The always-on timer also has one alarm comparator. Select + RTC_ALARM to expose it through /dev/rtc0. + config RP23XX_ADC bool "Enable ADC Support" default n diff --git a/arch/arm/src/rp23xx/Make.defs b/arch/arm/src/rp23xx/Make.defs index 1efbfeaabb3..a7371fd01ac 100644 --- a/arch/arm/src/rp23xx/Make.defs +++ b/arch/arm/src/rp23xx/Make.defs @@ -114,6 +114,9 @@ endif ifeq ($(CONFIG_RP23XX_RTC),y) CHIP_CSRCS += rp23xx_rtc.c +ifeq ($(CONFIG_RTC_DRIVER),y) +CHIP_CSRCS += rp23xx_rtc_lowerhalf.c +endif endif ifeq ($(CONFIG_RP23XX_OTP),y) diff --git a/arch/arm/src/rp23xx/rp23xx_rtc.c b/arch/arm/src/rp23xx/rp23xx_rtc.c index be78ad3f64d..88c5d051992 100644 --- a/arch/arm/src/rp23xx/rp23xx_rtc.c +++ b/arch/arm/src/rp23xx/rp23xx_rtc.c @@ -49,6 +49,7 @@ #include #include "arm_internal.h" +#include "rp23xx_rtc.h" #include "hardware/rp23xx_powman.h" #ifdef CONFIG_RTC @@ -73,6 +74,18 @@ #define LPOSC_FREQ_HZ 32768 +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM + +/* The always-on timer has one alarm comparator */ + +static struct rp23xx_alarm_state_s g_alarm; + +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -151,10 +164,169 @@ static void powman_set_ms(uint64_t ms) } } +#ifdef CONFIG_RTC_ALARM + +/* Disarm the comparator, mask its interrupt and clear its status. The + * comparator asserts while the time is past the alarm, so it must be + * disabled, not only acknowledged. + */ + +static void powman_alarm_disable(void) +{ + powman_clrbits(RP23XX_POWMAN_INTE, RP23XX_POWMAN_INTE_TIMER); + powman_clrbits(RP23XX_POWMAN_TIMER, RP23XX_POWMAN_TIMER_ALARM_ENAB); + powman_clrbits(RP23XX_POWMAN_TIMER, RP23XX_POWMAN_TIMER_ALARM); +} + +/* Program the comparator, disabled while the time is written, as + * powman_timer_enable_alarm_at_ms() in the Pico SDK does. + */ + +static void powman_set_alarm_ms(uint64_t ms) +{ + powman_setbits(RP23XX_POWMAN_INTE, RP23XX_POWMAN_INTE_TIMER); + powman_clrbits(RP23XX_POWMAN_TIMER, RP23XX_POWMAN_TIMER_ALARM_ENAB); + + powman_write(RP23XX_POWMAN_ALARM_TIME_15TO0, (uint32_t)(ms)); + powman_write(RP23XX_POWMAN_ALARM_TIME_31TO16, (uint32_t)(ms >> 16)); + powman_write(RP23XX_POWMAN_ALARM_TIME_47TO32, (uint32_t)(ms >> 32)); + powman_write(RP23XX_POWMAN_ALARM_TIME_63TO48, (uint32_t)(ms >> 48)); + + /* Drop any status latched from a previous alarm before re-enabling. */ + + powman_clrbits(RP23XX_POWMAN_TIMER, RP23XX_POWMAN_TIMER_ALARM); + powman_setbits(RP23XX_POWMAN_TIMER, RP23XX_POWMAN_TIMER_ALARM_ENAB); +} + +/**************************************************************************** + * Name: rp23xx_alarm_interrupt + * + * Description: + * POWMAN timer interrupt handler. Fires when the always-on timer reaches + * the programmed alarm time. + * + ****************************************************************************/ + +static int rp23xx_alarm_interrupt(int irq, FAR void *context, FAR void *arg) +{ + rp23xx_alarm_callback_t cb; + FAR void *cbarg; + + /* Disarm first, so that the callback can arm a new alarm */ + + powman_alarm_disable(); + + cb = g_alarm.cb; + cbarg = g_alarm.arg; + + g_alarm.active = false; + g_alarm.cb = NULL; + g_alarm.arg = NULL; + + if (cb != NULL) + { + cb(cbarg); + } + + return OK; +} + +#endif /* CONFIG_RTC_ALARM */ + /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: rp23xx_rtc_getms + * + * Description: + * Read the POWMAN always-on timer, in milliseconds since the epoch. + * + ****************************************************************************/ + +uint64_t rp23xx_rtc_getms(void) +{ + return powman_get_ms(); +} + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Name: rp23xx_rtc_setalarm + * + * Description: + * Arm the POWMAN alarm at an absolute time in milliseconds. + * + ****************************************************************************/ + +int rp23xx_rtc_setalarm(uint64_t time, rp23xx_alarm_callback_t cb, + FAR void *arg) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + if (time <= powman_get_ms()) + { + leave_critical_section(flags); + return -EINVAL; + } + + g_alarm.time = time; + g_alarm.cb = cb; + g_alarm.arg = arg; + g_alarm.active = true; + + powman_set_alarm_ms(time); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: rp23xx_rtc_cancelalarm + ****************************************************************************/ + +int rp23xx_rtc_cancelalarm(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + powman_alarm_disable(); + + g_alarm.active = false; + g_alarm.cb = NULL; + g_alarm.arg = NULL; + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: rp23xx_rtc_rdalarm + ****************************************************************************/ + +int rp23xx_rtc_rdalarm(FAR uint64_t *time) +{ + irqstate_t flags; + int ret = -ENODATA; + + flags = enter_critical_section(); + + if (g_alarm.active) + { + *time = g_alarm.time; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +#endif /* CONFIG_RTC_ALARM */ + /**************************************************************************** * Name: up_rtc_initialize * @@ -189,6 +361,15 @@ int up_rtc_initialize(void) } } +#ifdef CONFIG_RTC_ALARM + /* The alarm stays disarmed until it is set */ + + powman_alarm_disable(); + + irq_attach(RP23XX_POWMAN_IRQ_TIMER, rp23xx_alarm_interrupt, NULL); + up_enable_irq(RP23XX_POWMAN_IRQ_TIMER); +#endif + g_rtc_enabled = true; return OK; } diff --git a/arch/arm/src/rp23xx/rp23xx_rtc.h b/arch/arm/src/rp23xx/rp23xx_rtc.h new file mode 100644 index 00000000000..3a94c8240ad --- /dev/null +++ b/arch/arm/src/rp23xx/rp23xx_rtc.h @@ -0,0 +1,170 @@ +/**************************************************************************** + * arch/arm/src/rp23xx/rp23xx_rtc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_RP23XX_RP23XX_RTC_H +#define __ARCH_ARM_SRC_RP23XX_RP23XX_RTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#ifdef CONFIG_RP23XX_RTC + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifdef CONFIG_RTC_ALARM + +/* The always-on timer has one alarm comparator, so there is one alarm */ + +enum rp23xx_alarm_id_e +{ + RP23XX_ALARM0 = 0, + RP23XX_ALARM_LAST +}; + +/* Callback invoked from the POWMAN timer interrupt when the alarm fires. */ + +typedef CODE void (*rp23xx_alarm_callback_t)(FAR void *arg); + +/* State of the alarm */ + +struct rp23xx_alarm_state_s +{ + uint64_t time; /* Absolute alarm time, milliseconds */ + rp23xx_alarm_callback_t cb; /* Callback, NULL when none */ + FAR void *arg; /* Callback argument */ + bool active; /* True when the alarm was armed */ +}; + +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_rtc_getms + * + * Description: + * Read the POWMAN always-on timer, in milliseconds since the epoch. + * + ****************************************************************************/ + +uint64_t rp23xx_rtc_getms(void); + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Name: rp23xx_rtc_setalarm + * + * Description: + * Arm the POWMAN alarm at an absolute time. This replaces any alarm + * already armed. + * + * Input Parameters: + * time - Absolute alarm time in milliseconds since the epoch. + * cb - Called from the interrupt when the alarm fires, or NULL. + * arg - Argument passed back to the callback. + * + * Returned Value: + * Zero on success; a negated errno on failure. -EINVAL is returned when + * the requested time is not in the future. + * + ****************************************************************************/ + +int rp23xx_rtc_setalarm(uint64_t time, rp23xx_alarm_callback_t cb, + FAR void *arg); + +/**************************************************************************** + * Name: rp23xx_rtc_cancelalarm + * + * Description: + * Disarm the POWMAN alarm. Safe to call when no alarm is armed. + * + ****************************************************************************/ + +int rp23xx_rtc_cancelalarm(void); + +/**************************************************************************** + * Name: rp23xx_rtc_rdalarm + * + * Description: + * Read back the absolute time of the armed alarm. + * + * Returned Value: + * Zero on success, -ENODATA when no alarm is armed. + * + ****************************************************************************/ + +int rp23xx_rtc_rdalarm(FAR uint64_t *time); + +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rp23xx_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the POWMAN always-on timer. + * General usage: + * + * #include + * #include "rp23xx_rtc.h" + * + * struct rtc_lowerhalf_s *lower; + * lower = rp23xx_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_DRIVER +FAR struct rtc_lowerhalf_s *rp23xx_rtc_lowerhalf(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_RP23XX_RTC */ +#endif /* __ARCH_ARM_SRC_RP23XX_RP23XX_RTC_H */ diff --git a/arch/arm/src/rp23xx/rp23xx_rtc_lowerhalf.c b/arch/arm/src/rp23xx/rp23xx_rtc_lowerhalf.c new file mode 100644 index 00000000000..29e2f329b36 --- /dev/null +++ b/arch/arm/src/rp23xx/rp23xx_rtc_lowerhalf.c @@ -0,0 +1,432 @@ +/**************************************************************************** + * arch/arm/src/rp23xx/rp23xx_rtc_lowerhalf.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "rp23xx_rtc.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM + +/* Bridges the chip-level alarm callback, which carries only an opaque + * argument, to the RTC upper-half callback, which also wants an alarm id. + */ + +struct rp23xx_cbinfo_s +{ + volatile rtc_alarm_callback_t cb; /* Upper-half callback */ + volatile FAR void *priv; /* Upper-half argument */ +}; +#endif + +struct rp23xx_lowerhalf_s +{ + /* This is the contained reference to the read-only, lower-half operations + * vtable (which may lie in FLASH). + */ + + FAR const struct rtc_ops_s *ops; + + /* Data following is private to this driver and not visible outside of + * this file. + */ + + mutex_t devlock; /* Threads accessing the device */ + +#ifdef CONFIG_RTC_ALARM + struct rp23xx_cbinfo_s cbinfo; /* Alarm callback information */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int rp23xx_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime); +static int rp23xx_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime); +static bool rp23xx_havesettime(FAR struct rtc_lowerhalf_s *lower); + +#ifdef CONFIG_RTC_ALARM +static int rp23xx_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo); +static int rp23xx_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *info); +static int rp23xx_cancelalarm(FAR struct rtc_lowerhalf_s *lower, + int alarmid); +static int rp23xx_rdalarm(FAR struct rtc_lowerhalf_s *lower, + FAR struct lower_rdalarm_s *alarminfo); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* RP2350 RTC driver operations */ + +static const struct rtc_ops_s g_rtc_ops = +{ + .rdtime = rp23xx_rdtime, + .settime = rp23xx_settime, + .havesettime = rp23xx_havesettime, +#ifdef CONFIG_RTC_ALARM + .setalarm = rp23xx_setalarm, + .setrelative = rp23xx_setrelative, + .cancelalarm = rp23xx_cancelalarm, + .rdalarm = rp23xx_rdalarm, +#endif +}; + +/* RP2350 RTC device state */ + +static struct rp23xx_lowerhalf_s g_rtc_lowerhalf = +{ + .ops = &g_rtc_ops, + .devlock = NXMUTEX_INITIALIZER, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Name: rp23xx_alarm_callback + * + * Description: + * Invoked from the POWMAN timer interrupt when the alarm expires. + * + ****************************************************************************/ + +static void rp23xx_alarm_callback(FAR void *arg) +{ + FAR struct rp23xx_lowerhalf_s *priv = arg; + FAR struct rp23xx_cbinfo_s *cbinfo = &priv->cbinfo; + rtc_alarm_callback_t cb; + FAR void *cbarg; + + /* Sample and clear the callback before invoking it, so that the callback + * is free to arm a new alarm. + */ + + cb = (rtc_alarm_callback_t)cbinfo->cb; + cbarg = (FAR void *)cbinfo->priv; + + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + if (cb != NULL) + { + cb(cbarg, RP23XX_ALARM0); + } +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rp23xx_rdtime + * + * Description: + * Implements the rdtime() method of the RTC driver interface. + * + ****************************************************************************/ + +static int rp23xx_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime) +{ + time_t secs; + + secs = (time_t)(rp23xx_rtc_getms() / MSEC_PER_SEC); + + if (gmtime_r(&secs, (FAR struct tm *)rtctime) == NULL) + { + return -EINVAL; + } + + return OK; +} + +/**************************************************************************** + * Name: rp23xx_settime + * + * Description: + * Implements the settime() method of the RTC driver interface. + * + ****************************************************************************/ + +static int rp23xx_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime) +{ + struct timespec ts; + + /* timegm() normalises its argument, so convert a copy */ + + struct tm tm = *(FAR const struct tm *)rtctime; + + ts.tv_sec = timegm(&tm); + ts.tv_nsec = 0; + + return up_rtc_settime(&ts); +} + +/**************************************************************************** + * Name: rp23xx_havesettime + * + * Description: + * Implements the havesettime() method of the RTC driver interface. + * + ****************************************************************************/ + +static bool rp23xx_havesettime(FAR struct rtc_lowerhalf_s *lower) +{ + /* POWMAN has no flag that the time was set; report the counter running */ + + return g_rtc_enabled; +} + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Name: rp23xx_setalarm + * + * Description: + * Implements the setalarm() method of the RTC driver interface. + * + ****************************************************************************/ + +static int rp23xx_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo) +{ + FAR struct rp23xx_lowerhalf_s *priv; + FAR struct rp23xx_cbinfo_s *cbinfo; + struct tm tm; + uint64_t ms; + int ret; + + DEBUGASSERT(lower != NULL && alarminfo != NULL); + priv = (FAR struct rp23xx_lowerhalf_s *)lower; + + if (alarminfo->id != RP23XX_ALARM0) + { + return -EINVAL; + } + + ret = nxmutex_lock(&priv->devlock); + if (ret < 0) + { + return ret; + } + + tm = *(FAR const struct tm *)&alarminfo->time; + ms = (uint64_t)timegm(&tm) * MSEC_PER_SEC; + + /* Remember the callback information before arming: the alarm can in + * principle fire the moment it is enabled. + */ + + cbinfo = &priv->cbinfo; + cbinfo->cb = alarminfo->cb; + cbinfo->priv = alarminfo->priv; + + ret = rp23xx_rtc_setalarm(ms, rp23xx_alarm_callback, priv); + if (ret < 0) + { + cbinfo->cb = NULL; + cbinfo->priv = NULL; + } + + nxmutex_unlock(&priv->devlock); + return ret; +} + +/**************************************************************************** + * Name: rp23xx_setrelative + * + * Description: + * Implements the setrelative() method of the RTC driver interface. + * + ****************************************************************************/ + +static int rp23xx_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *info) +{ + FAR struct rp23xx_lowerhalf_s *priv; + FAR struct rp23xx_cbinfo_s *cbinfo; + uint64_t ms; + int ret; + + DEBUGASSERT(lower != NULL && info != NULL); + priv = (FAR struct rp23xx_lowerhalf_s *)lower; + + if (info->id != RP23XX_ALARM0 || info->reltime <= 0) + { + return -EINVAL; + } + + ret = nxmutex_lock(&priv->devlock); + if (ret < 0) + { + return ret; + } + + /* Use the millisecond counter, not the system time in whole seconds */ + + ms = rp23xx_rtc_getms() + (uint64_t)info->reltime * MSEC_PER_SEC; + + cbinfo = &priv->cbinfo; + cbinfo->cb = info->cb; + cbinfo->priv = info->priv; + + ret = rp23xx_rtc_setalarm(ms, rp23xx_alarm_callback, priv); + if (ret < 0) + { + cbinfo->cb = NULL; + cbinfo->priv = NULL; + } + + nxmutex_unlock(&priv->devlock); + return ret; +} + +/**************************************************************************** + * Name: rp23xx_cancelalarm + * + * Description: + * Implements the cancelalarm() method of the RTC driver interface. + * + ****************************************************************************/ + +static int rp23xx_cancelalarm(FAR struct rtc_lowerhalf_s *lower, + int alarmid) +{ + FAR struct rp23xx_lowerhalf_s *priv; + FAR struct rp23xx_cbinfo_s *cbinfo; + int ret; + + DEBUGASSERT(lower != NULL); + priv = (FAR struct rp23xx_lowerhalf_s *)lower; + + if (alarmid != RP23XX_ALARM0) + { + return -EINVAL; + } + + ret = nxmutex_lock(&priv->devlock); + if (ret < 0) + { + return ret; + } + + cbinfo = &priv->cbinfo; + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + ret = rp23xx_rtc_cancelalarm(); + + nxmutex_unlock(&priv->devlock); + return ret; +} + +/**************************************************************************** + * Name: rp23xx_rdalarm + * + * Description: + * Implements the rdalarm() method of the RTC driver interface. + * + ****************************************************************************/ + +static int rp23xx_rdalarm(FAR struct rtc_lowerhalf_s *lower, + FAR struct lower_rdalarm_s *alarminfo) +{ + uint64_t ms; + time_t secs; + int ret; + + DEBUGASSERT(lower != NULL && alarminfo != NULL && + alarminfo->time != NULL); + + if (alarminfo->id != RP23XX_ALARM0) + { + return -EINVAL; + } + + /* An alarm that is not armed is not an error: the upper half reports it + * as inactive. + */ + + ret = rp23xx_rtc_rdalarm(&ms); + if (ret == -ENODATA) + { + ms = 0; + } + else if (ret < 0) + { + return ret; + } + + secs = (time_t)(ms / MSEC_PER_SEC); + + if (gmtime_r(&secs, (FAR struct tm *)alarminfo->time) == NULL) + { + return -EINVAL; + } + + return OK; +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the POWMAN always-on timer. + * + ****************************************************************************/ + +FAR struct rtc_lowerhalf_s *rp23xx_rtc_lowerhalf(void) +{ + return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf; +} diff --git a/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c b/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c index 7d0d47506a5..634899a1095 100644 --- a/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c +++ b/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c @@ -58,6 +58,11 @@ # include "rp23xx_flash_mtd.h" #endif +#if defined(CONFIG_RP23XX_RTC) && defined(CONFIG_RTC_DRIVER) +# include +# include "rp23xx_rtc.h" +#endif + #ifdef CONFIG_RP23XX_OTP # include "rp23xx_otp.h" #endif @@ -462,6 +467,27 @@ int rp23xx_common_bringup(void) } #endif +#if defined(CONFIG_RP23XX_RTC) && defined(CONFIG_RTC_DRIVER) + /* Register the always-on timer as /dev/rtc0 */ + + { + FAR struct rtc_lowerhalf_s *rtclower = rp23xx_rtc_lowerhalf(); + + if (rtclower == NULL) + { + syslog(LOG_ERR, "Failed to instantiate the RTC lower half\n"); + } + else + { + ret = rtc_initialize(0, rtclower); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to bind /dev/rtc0: %d\n", ret); + } + } + } +#endif + #ifdef CONFIG_RP23XX_I2S ret = board_i2sdev_initialize(0); if (ret < 0)