drivers: rtc: add rtc support for apollo3&3p

Add RTC support for Apollo3 and Apollo3 Plus Soc

Signed-off-by: Hao Luo <hluo@ambiq.com>
This commit is contained in:
Hao Luo 2024-12-12 15:30:01 +08:00 committed by Benjamin Cabé
parent 888bf137b4
commit 63904f3a19
6 changed files with 82 additions and 21 deletions

View file

@ -30,6 +30,7 @@
sw1 = &button1;
bootloader-led0 = &led0;
mcuboot-led0 = &led0;
rtc = &rtc0;
};
leds {
@ -189,6 +190,11 @@
status = "okay";
};
&rtc0 {
status = "okay";
clock = "XTAL";
};
&adc0 {
compatible = "ambiq,adc";
pinctrl-0 = <&adc0_default>;

View file

@ -2,6 +2,7 @@
#include <ambiq/ambiq_apollo3p_blue.dtsi>
#include "apollo3p_evb-pinctrl.dtsi"
#include <zephyr/dt-bindings/input/input-event-codes.h>
/ {
model = "Ambiq Apollo3 Blue Plus evaluation board";
@ -25,6 +26,7 @@
led2 = &led2;
sw0 = &button0;
sw1 = &button1;
rtc = &rtc0;
};
leds {
@ -56,14 +58,17 @@
button0: button_0 {
gpios = <&gpio0_31 16 GPIO_ACTIVE_LOW>;
label = "BTN0";
zephyr,code = <INPUT_KEY_0>;
};
button1: button_1 {
gpios = <&gpio0_31 18 GPIO_ACTIVE_LOW>;
label = "BTN1";
zephyr,code = <INPUT_KEY_1>;
};
button2: button_2 {
gpios = <&gpio0_31 19 GPIO_ACTIVE_LOW>;
label = "BTN2";
zephyr,code = <INPUT_KEY_2>;
};
};
};
@ -163,6 +168,11 @@
status = "okay";
};
&rtc0 {
status = "okay";
clock = "XTAL";
};
&adc0 {
compatible = "ambiq,adc";
pinctrl-0 = <&adc0_default>;

View file

@ -42,7 +42,11 @@ struct ambiq_rtc_data {
static void rtc_time_to_ambiq_time_set(const struct rtc_time *tm, am_hal_rtc_time_t *atm)
{
atm->ui32CenturyBit = ((tm->tm_year <= 99) || (tm->tm_year >= 200));
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
atm->ui32Century = ((tm->tm_year <= 99) || (tm->tm_year >= 200));
#else
atm->ui32CenturyBit = ((tm->tm_year > 99) && (tm->tm_year < 200));
#endif
atm->ui32Year = tm->tm_year;
if (tm->tm_year > 99) {
atm->ui32Year = tm->tm_year % 100;
@ -68,11 +72,19 @@ static void rtc_time_to_ambiq_time_set(const struct rtc_time *tm, am_hal_rtc_tim
static void ambiq_time_to_rtc_time_set(const am_hal_rtc_time_t *atm, struct rtc_time *tm)
{
tm->tm_year = atm->ui32Year;
if (atm->ui32CenturyBit == 0) {
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
if (atm->ui32Century == 0) {
tm->tm_year += 100;
} else {
tm->tm_year += 200;
}
#else
if (atm->ui32CenturyBit == 0) {
tm->tm_year += 200;
} else {
tm->tm_year += 100;
}
#endif
tm->tm_wday = atm->ui32Weekday;
tm->tm_mon = atm->ui32Month - 1;
tm->tm_mday = atm->ui32DayOfMonth;
@ -180,8 +192,6 @@ static int ambiq_rtc_alarm_get_supported_fields(const struct device *dev,
static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
struct rtc_time *timeptr)
{
int err = 0;
am_hal_rtc_time_t ambiq_time = {0};
struct ambiq_rtc_data *data = dev->data;
@ -192,11 +202,11 @@ static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint1
k_spinlock_key_t key = k_spin_lock(&data->lock);
err = am_hal_rtc_alarm_get(&ambiq_time, NULL);
if (err != 0) {
LOG_DBG("Invalid Input Value");
return -EINVAL;
}
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
am_hal_rtc_alarm_get(&ambiq_time);
#else
am_hal_rtc_alarm_get(&ambiq_time, NULL);
#endif
ambiq_time_to_rtc_time_set(&ambiq_time, timeptr);
@ -208,13 +218,12 @@ static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint1
k_spin_unlock(&data->lock, key);
return err;
return 0;
}
static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
const struct rtc_time *timeptr)
{
int err = 0;
struct ambiq_rtc_data *data = dev->data;
am_hal_rtc_time_t ambiq_time = {0};
uint16_t mask_available;
@ -240,8 +249,13 @@ static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint1
k_spinlock_key_t key = k_spin_lock(&data->lock);
/* Disable and clear the alarm */
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
am_hal_rtc_int_disable(AM_HAL_RTC_INT_ALM);
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
#else
am_hal_rtc_interrupt_disable(AM_HAL_RTC_INT_ALM);
am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM);
#endif
/* When mask is 0 */
if (mask == 0) {
@ -258,18 +272,18 @@ static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint1
rtc_time_to_ambiq_time_set(timeptr, &ambiq_time);
/* Set RTC ALARM, Ambiq must have interval != AM_HAL_RTC_ALM_RPT_DIS */
if (0 != am_hal_rtc_alarm_set(&ambiq_time, AM_HAL_RTC_ALM_RPT_YR)) {
LOG_DBG("Invalid Input Value");
err = -EINVAL;
goto unlock;
}
am_hal_rtc_alarm_set(&ambiq_time, AM_HAL_RTC_ALM_RPT_YR);
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
am_hal_rtc_int_enable(AM_HAL_RTC_INT_ALM);
#else
am_hal_rtc_interrupt_enable(AM_HAL_RTC_INT_ALM);
#endif
unlock:
k_spin_unlock(&data->lock, key);
return err;
return 0;
}
static int ambiq_rtc_alarm_is_pending(const struct device *dev, uint16_t id)
@ -292,7 +306,11 @@ static int ambiq_rtc_alarm_is_pending(const struct device *dev, uint16_t id)
static void ambiq_rtc_isr(const struct device *dev)
{
/* Clear the RTC alarm interrupt. 8*/
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
#else
am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM);
#endif
#if defined(CONFIG_RTC_ALARM)
struct ambiq_rtc_data *data = dev->data;
@ -321,7 +339,11 @@ static int ambiq_rtc_alarm_set_callback(const struct device *dev, uint16_t id,
data->alarm_user_callback = callback;
data->alarm_user_data = user_data;
if ((callback == NULL) && (user_data == NULL)) {
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
am_hal_rtc_int_disable(AM_HAL_RTC_INT_ALM);
#else
am_hal_rtc_interrupt_disable(AM_HAL_RTC_INT_ALM);
#endif
}
}
@ -332,14 +354,16 @@ static int ambiq_rtc_alarm_set_callback(const struct device *dev, uint16_t id,
static int ambiq_rtc_init(const struct device *dev)
{
const struct ambiq_rtc_config *config = dev->config;
#
#ifdef CONFIG_RTC_ALARM
struct ambiq_rtc_data *data = dev->data;
#endif
/* Enable the clock for RTC. */
am_hal_clkgen_control(config->clk_src, NULL);
/* Enable the clock for RTC. */
#if defined(CONFIG_SOC_SERIES_APOLLO3X)
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START + config->clk_src, NULL);
#endif
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_RTC_SEL_XTAL + config->clk_src, NULL);
/* Enable the RTC. */
am_hal_rtc_osc_enable();

View file

@ -349,6 +349,14 @@
ambiq,pwrcfg = <&pwrcfg 0x8 0x800>;
};
rtc0: rtc@40004240 {
compatible = "ambiq,rtc";
reg = <0x40004240 0xD0>;
interrupts = <2 0>;
alarms-count = <1>;
status = "disabled";
};
bleif: spi@5000c000 {
compatible = "ambiq,spi-bleif";
reg = <0x5000c000 0x414>;

View file

@ -390,6 +390,14 @@
ambiq,pwrcfg = <&pwrcfg 0x8 0x2000>;
};
rtc0: rtc@40004240 {
compatible = "ambiq,rtc";
reg = <0x40004240 0xD0>;
interrupts = <2 0>;
alarms-count = <1>;
status = "disabled";
};
bleif: spi@5000c000 {
compatible = "ambiq,spi-bleif";
reg = <0x5000c000 0x414>;

View file

@ -0,0 +1,5 @@
# Copyright (c) 2024, Ambiq Micro Inc. <www.ambiq.com>
# SPDX-License-Identifier: Apache-2.0
CONFIG_RTC_ALARM=y
CONFIG_TEST_RTC_ALARM_TIME_MASK=79