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

View file

@ -2,6 +2,7 @@
#include <ambiq/ambiq_apollo3p_blue.dtsi> #include <ambiq/ambiq_apollo3p_blue.dtsi>
#include "apollo3p_evb-pinctrl.dtsi" #include "apollo3p_evb-pinctrl.dtsi"
#include <zephyr/dt-bindings/input/input-event-codes.h>
/ { / {
model = "Ambiq Apollo3 Blue Plus evaluation board"; model = "Ambiq Apollo3 Blue Plus evaluation board";
@ -25,6 +26,7 @@
led2 = &led2; led2 = &led2;
sw0 = &button0; sw0 = &button0;
sw1 = &button1; sw1 = &button1;
rtc = &rtc0;
}; };
leds { leds {
@ -56,14 +58,17 @@
button0: button_0 { button0: button_0 {
gpios = <&gpio0_31 16 GPIO_ACTIVE_LOW>; gpios = <&gpio0_31 16 GPIO_ACTIVE_LOW>;
label = "BTN0"; label = "BTN0";
zephyr,code = <INPUT_KEY_0>;
}; };
button1: button_1 { button1: button_1 {
gpios = <&gpio0_31 18 GPIO_ACTIVE_LOW>; gpios = <&gpio0_31 18 GPIO_ACTIVE_LOW>;
label = "BTN1"; label = "BTN1";
zephyr,code = <INPUT_KEY_1>;
}; };
button2: button_2 { button2: button_2 {
gpios = <&gpio0_31 19 GPIO_ACTIVE_LOW>; gpios = <&gpio0_31 19 GPIO_ACTIVE_LOW>;
label = "BTN2"; label = "BTN2";
zephyr,code = <INPUT_KEY_2>;
}; };
}; };
}; };
@ -163,6 +168,11 @@
status = "okay"; status = "okay";
}; };
&rtc0 {
status = "okay";
clock = "XTAL";
};
&adc0 { &adc0 {
compatible = "ambiq,adc"; compatible = "ambiq,adc";
pinctrl-0 = <&adc0_default>; 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) 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; atm->ui32Year = tm->tm_year;
if (tm->tm_year > 99) { if (tm->tm_year > 99) {
atm->ui32Year = tm->tm_year % 100; 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) static void ambiq_time_to_rtc_time_set(const am_hal_rtc_time_t *atm, struct rtc_time *tm)
{ {
tm->tm_year = atm->ui32Year; tm->tm_year = atm->ui32Year;
if (atm->ui32CenturyBit == 0) { #if defined(CONFIG_SOC_SERIES_APOLLO3X)
if (atm->ui32Century == 0) {
tm->tm_year += 100; tm->tm_year += 100;
} else { } else {
tm->tm_year += 200; 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_wday = atm->ui32Weekday;
tm->tm_mon = atm->ui32Month - 1; tm->tm_mon = atm->ui32Month - 1;
tm->tm_mday = atm->ui32DayOfMonth; 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, static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
struct rtc_time *timeptr) struct rtc_time *timeptr)
{ {
int err = 0;
am_hal_rtc_time_t ambiq_time = {0}; am_hal_rtc_time_t ambiq_time = {0};
struct ambiq_rtc_data *data = dev->data; 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); k_spinlock_key_t key = k_spin_lock(&data->lock);
err = am_hal_rtc_alarm_get(&ambiq_time, NULL); #if defined(CONFIG_SOC_SERIES_APOLLO3X)
if (err != 0) { am_hal_rtc_alarm_get(&ambiq_time);
LOG_DBG("Invalid Input Value"); #else
return -EINVAL; am_hal_rtc_alarm_get(&ambiq_time, NULL);
} #endif
ambiq_time_to_rtc_time_set(&ambiq_time, timeptr); 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); 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, static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
const struct rtc_time *timeptr) const struct rtc_time *timeptr)
{ {
int err = 0;
struct ambiq_rtc_data *data = dev->data; struct ambiq_rtc_data *data = dev->data;
am_hal_rtc_time_t ambiq_time = {0}; am_hal_rtc_time_t ambiq_time = {0};
uint16_t mask_available; 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); k_spinlock_key_t key = k_spin_lock(&data->lock);
/* Disable and clear the alarm */ /* 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_disable(AM_HAL_RTC_INT_ALM);
am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM); am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM);
#endif
/* When mask is 0 */ /* When mask is 0 */
if (mask == 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); rtc_time_to_ambiq_time_set(timeptr, &ambiq_time);
/* Set RTC ALARM, Ambiq must have interval != AM_HAL_RTC_ALM_RPT_DIS */ /* 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)) { am_hal_rtc_alarm_set(&ambiq_time, AM_HAL_RTC_ALM_RPT_YR);
LOG_DBG("Invalid Input Value");
err = -EINVAL;
goto unlock;
}
#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); am_hal_rtc_interrupt_enable(AM_HAL_RTC_INT_ALM);
#endif
unlock: unlock:
k_spin_unlock(&data->lock, key); k_spin_unlock(&data->lock, key);
return err; return 0;
} }
static int ambiq_rtc_alarm_is_pending(const struct device *dev, uint16_t id) 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) static void ambiq_rtc_isr(const struct device *dev)
{ {
/* Clear the RTC alarm interrupt. 8*/ /* 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); am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM);
#endif
#if defined(CONFIG_RTC_ALARM) #if defined(CONFIG_RTC_ALARM)
struct ambiq_rtc_data *data = dev->data; 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_callback = callback;
data->alarm_user_data = user_data; data->alarm_user_data = user_data;
if ((callback == NULL) && (user_data == NULL)) { 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); 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) static int ambiq_rtc_init(const struct device *dev)
{ {
const struct ambiq_rtc_config *config = dev->config; const struct ambiq_rtc_config *config = dev->config;
#
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
struct ambiq_rtc_data *data = dev->data; struct ambiq_rtc_data *data = dev->data;
#endif #endif
/* Enable the clock for RTC. */ /* Enable the clock for RTC. */
am_hal_clkgen_control(config->clk_src, NULL); #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. */ /* Enable the RTC. */
am_hal_rtc_osc_enable(); am_hal_rtc_osc_enable();

View file

@ -349,6 +349,14 @@
ambiq,pwrcfg = <&pwrcfg 0x8 0x800>; 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 { bleif: spi@5000c000 {
compatible = "ambiq,spi-bleif"; compatible = "ambiq,spi-bleif";
reg = <0x5000c000 0x414>; reg = <0x5000c000 0x414>;

View file

@ -390,6 +390,14 @@
ambiq,pwrcfg = <&pwrcfg 0x8 0x2000>; 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 { bleif: spi@5000c000 {
compatible = "ambiq,spi-bleif"; compatible = "ambiq,spi-bleif";
reg = <0x5000c000 0x414>; 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