drivers: rtc: rpi_pico: Add support for the Raspberry Pi Pico RTC
This adds the minimal get_time/set_time support for the rp2040 and enables support by default on the Pico boards. This doesn't support configuring the clock source or alarm interrupts yet. Signed-off-by: Andrew Featherstone <andrew.featherstone@gmail.com>
This commit is contained in:
parent
4c880f4b0a
commit
df8c89b528
|
@ -24,6 +24,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
|
rtc = &rtc;
|
||||||
watchdog0 = &wdt0;
|
watchdog0 = &wdt0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,6 +134,11 @@
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&rtc {
|
||||||
|
clocks = <&clocks RPI_PICO_CLKID_CLK_RTC>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
&adc {
|
&adc {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-0 = <&adc_default>;
|
pinctrl-0 = <&adc_default>;
|
||||||
|
|
|
@ -19,3 +19,4 @@ zephyr_library_sources_ifdef(CONFIG_RTC_SHELL rtc_shell.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c)
|
zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c)
|
zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM rtc_sam.c)
|
zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM rtc_sam.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_RTC_RPI_PICO rtc_rpi_pico.c)
|
||||||
|
|
|
@ -45,11 +45,12 @@ source "drivers/rtc/Kconfig.am1805"
|
||||||
source "drivers/rtc/Kconfig.ds1307"
|
source "drivers/rtc/Kconfig.ds1307"
|
||||||
source "drivers/rtc/Kconfig.emul"
|
source "drivers/rtc/Kconfig.emul"
|
||||||
source "drivers/rtc/Kconfig.fake"
|
source "drivers/rtc/Kconfig.fake"
|
||||||
|
source "drivers/rtc/Kconfig.mc146818"
|
||||||
source "drivers/rtc/Kconfig.pcf8523"
|
source "drivers/rtc/Kconfig.pcf8523"
|
||||||
source "drivers/rtc/Kconfig.pcf8563"
|
source "drivers/rtc/Kconfig.pcf8563"
|
||||||
source "drivers/rtc/Kconfig.mc146818"
|
source "drivers/rtc/Kconfig.rpi_pico"
|
||||||
source "drivers/rtc/Kconfig.sam"
|
source "drivers/rtc/Kconfig.sam"
|
||||||
source "drivers/rtc/Kconfig.stm32"
|
|
||||||
source "drivers/rtc/Kconfig.smartbond"
|
source "drivers/rtc/Kconfig.smartbond"
|
||||||
|
source "drivers/rtc/Kconfig.stm32"
|
||||||
|
|
||||||
endif # RTC
|
endif # RTC
|
||||||
|
|
9
drivers/rtc/Kconfig.rpi_pico
Normal file
9
drivers/rtc/Kconfig.rpi_pico
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Copyright (c) 2023 Andrew Featherstone
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config RTC_RPI_PICO
|
||||||
|
bool "Raspberry Pi Pico RTC driver"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_RASPBERRYPI_PICO_RTC_ENABLED
|
||||||
|
select PICOSDK_USE_RTC
|
||||||
|
depends on RESET
|
112
drivers/rtc/rtc_rpi_pico.c
Normal file
112
drivers/rtc/rtc_rpi_pico.c
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Andrew Featherstone
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/clock_control.h>
|
||||||
|
#include <zephyr/drivers/rtc.h>
|
||||||
|
#include <zephyr/irq.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/spinlock.h>
|
||||||
|
|
||||||
|
#include <hardware/rtc.h>
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT raspberrypi_pico_rtc
|
||||||
|
|
||||||
|
#define CLK_DRV DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0))
|
||||||
|
#define CLK_ID (clock_control_subsys_t) DT_INST_PHA_BY_IDX(0, clocks, 0, clk_id)
|
||||||
|
|
||||||
|
/* struct tm start time: 1st, Jan, 1900 */
|
||||||
|
#define TM_YEAR_REF 1900
|
||||||
|
/* See section 4.8.1 of the RP2040 datasheet. */
|
||||||
|
#define RP2040_RTC_YEAR_MAX 4095
|
||||||
|
struct rtc_rpi_pico_data {
|
||||||
|
struct k_spinlock lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(rtc_rpi, CONFIG_RTC_LOG_LEVEL);
|
||||||
|
|
||||||
|
static int rtc_rpi_pico_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = clock_control_on(CLK_DRV, CLK_ID);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_init();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtc_rpi_pico_set_time(const struct device *dev, const struct rtc_time *timeptr)
|
||||||
|
{
|
||||||
|
struct rtc_rpi_pico_data *data = dev->data;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (timeptr->tm_year + TM_YEAR_REF > RP2040_RTC_YEAR_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeptr->tm_wday == -1) {
|
||||||
|
/* day of the week is expected */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_spinlock_key_t key = k_spin_lock(&data->lock);
|
||||||
|
datetime_t dt = {
|
||||||
|
.year = timeptr->tm_year + TM_YEAR_REF,
|
||||||
|
.month = timeptr->tm_mon + 1,
|
||||||
|
.day = timeptr->tm_mday,
|
||||||
|
.dotw = timeptr->tm_wday,
|
||||||
|
.hour = timeptr->tm_hour,
|
||||||
|
.min = timeptr->tm_min,
|
||||||
|
.sec = timeptr->tm_sec,
|
||||||
|
};
|
||||||
|
/* Use the validation in the Pico SDK. */
|
||||||
|
if (!rtc_set_datetime(&dt)) {
|
||||||
|
err = -EINVAL;
|
||||||
|
}
|
||||||
|
k_spin_unlock(&data->lock, key);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtc_rpi_pico_get_time(const struct device *dev, struct rtc_time *timeptr)
|
||||||
|
{
|
||||||
|
struct rtc_rpi_pico_data *data = dev->data;
|
||||||
|
datetime_t dt;
|
||||||
|
int err = 0;
|
||||||
|
k_spinlock_key_t key = k_spin_lock(&data->lock);
|
||||||
|
|
||||||
|
if (!rtc_get_datetime(&dt)) {
|
||||||
|
err = -ENODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeptr->tm_sec = dt.sec;
|
||||||
|
timeptr->tm_min = dt.min;
|
||||||
|
timeptr->tm_hour = dt.hour;
|
||||||
|
timeptr->tm_mday = dt.day;
|
||||||
|
timeptr->tm_mon = dt.month - 1;
|
||||||
|
timeptr->tm_year = dt.year - TM_YEAR_REF;
|
||||||
|
timeptr->tm_wday = dt.dotw;
|
||||||
|
/* unknown values */
|
||||||
|
timeptr->tm_yday = -1;
|
||||||
|
timeptr->tm_isdst = -1;
|
||||||
|
timeptr->tm_nsec = 0;
|
||||||
|
k_spin_unlock(&data->lock, key);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rtc_driver_api rtc_rpi_pico_driver_api = {
|
||||||
|
.set_time = rtc_rpi_pico_set_time,
|
||||||
|
.get_time = rtc_rpi_pico_get_time,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rtc_rpi_pico_data rtc_data;
|
||||||
|
|
||||||
|
DEVICE_DT_INST_DEFINE(0, &rtc_rpi_pico_init, NULL, &rtc_data, NULL, POST_KERNEL,
|
||||||
|
CONFIG_RTC_INIT_PRIORITY, &rtc_rpi_pico_driver_api);
|
|
@ -399,6 +399,14 @@
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_PIO1>;
|
resets = <&reset RPI_PICO_RESETS_RESET_PIO1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rtc: rtc@4005c000 {
|
||||||
|
compatible = "raspberrypi,pico-rtc";
|
||||||
|
reg = <0x4005c000 DT_SIZE_K(4)>;
|
||||||
|
interrupts = <25 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
|
resets = <&reset RPI_PICO_RESETS_RESET_RTC>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pinctrl: pin-controller {
|
pinctrl: pin-controller {
|
||||||
|
|
12
dts/bindings/rtc/raspberrypi,pico-rtc.yaml
Normal file
12
dts/bindings/rtc/raspberrypi,pico-rtc.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (c) 2024 Andrew Featherstone <andrew.featherstone@gmail.com>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: RaspberryPi Pico RTC
|
||||||
|
|
||||||
|
compatible: "raspberrypi,pico-rtc"
|
||||||
|
|
||||||
|
include: [rtc.yaml, reset-device.yaml]
|
||||||
|
|
||||||
|
properties:
|
||||||
|
reg:
|
||||||
|
required: true
|
|
@ -113,6 +113,11 @@ if(CONFIG_HAS_RPI_PICO)
|
||||||
zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_CLAIM
|
zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_CLAIM
|
||||||
${rp2_common_dir}/hardware_claim/include)
|
${rp2_common_dir}/hardware_claim/include)
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_RTC
|
||||||
|
${rp2_common_dir}/hardware_rtc/rtc.c)
|
||||||
|
zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_RTC
|
||||||
|
${rp2_common_dir}/hardware_rtc/include)
|
||||||
|
|
||||||
# Some flash driver functions must be executed from the RAM.
|
# Some flash driver functions must be executed from the RAM.
|
||||||
# Originally pico-sdk places them in the RW data section, so this
|
# Originally pico-sdk places them in the RW data section, so this
|
||||||
# implementation does the same.
|
# implementation does the same.
|
||||||
|
|
|
@ -49,3 +49,8 @@ config PICOSDK_USE_TIMER
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
Use the TIMER driver from pico-sdk
|
Use the TIMER driver from pico-sdk
|
||||||
|
|
||||||
|
config PICOSDK_USE_RTC
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Use the RTC driver from pico-sdk
|
||||||
|
|
Loading…
Reference in a new issue