diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index bdfa9a72d83..14dfb0f9544 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -214,6 +214,7 @@ endchoice # On-board Crystal Frequency config ESP32_RT_TIMER bool "Real-time Timer" default n + select ESP32_TIMER0 config ESP32_PARTITION bool "ESP32 Partition" diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index 964468a5187..113edd9fab7 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -193,6 +193,10 @@ ifeq ($(CONFIG_ESP32_AES_ACCELERATOR),y) CHIP_CSRCS += esp32_aes.c endif +ifeq ($(CONFIG_RTC_DRIVER),y) +CHIP_CSRCS += esp32_rtc_lowerhalf.c +endif + ifeq ($(CONFIG_ESP32_WIRELESS),y) WIRELESS_DRV_UNPACK = esp-wireless-drivers-3rdparty WIRELESS_DRV_ID = 2b53111 diff --git a/arch/xtensa/src/esp32/esp32_rtc.c b/arch/xtensa/src/esp32/esp32_rtc.c index 0c4be46b58d..47cd168f9a4 100644 --- a/arch/xtensa/src/esp32/esp32_rtc.c +++ b/arch/xtensa/src/esp32/esp32_rtc.c @@ -24,13 +24,19 @@ #include #include +#include + +#include +#include #include "esp32_rtc.h" #include "esp32_clockconfig.h" +#include "esp32_rt_timer.h" + #include "hardware/esp32_rtccntl.h" #include "hardware/esp32_dport.h" #include "hardware/esp32_i2s.h" -#include "esp32_rtc.h" + #include "xtensa.h" #include "xtensa_attr.h" @@ -124,6 +130,25 @@ .fe_pd = (val), \ } +#ifdef CONFIG_RTC_DRIVER +/* The magic data for the struct esp32_rtc_backup_s that is in RTC slow + * memory. + */ + +# define MAGIC_RTC_SAVE (UINT64_C(0x11223344556677)) +#endif + +/* RTC Memory & Store Register usage */ + +#define RTC_SLOW_CLK_CAL_REG RTC_CNTL_STORE1_REG /* RTC_SLOW_CLK calibration value */ +#define RTC_BOOT_TIME_LOW_REG RTC_CNTL_STORE2_REG /* Boot time, low word */ +#define RTC_BOOT_TIME_HIGH_REG RTC_CNTL_STORE3_REG /* Boot time, high word */ +#define RTC_XTAL_FREQ_REG RTC_CNTL_STORE4_REG /* External XTAL frequency */ +#define RTC_APB_FREQ_REG RTC_CNTL_STORE5_REG /* APB bus frequency */ +#define RTC_ENTRY_ADDR_REG RTC_CNTL_STORE6_REG /* FAST_RTC_MEMORY_ENTRY */ +#define RTC_RESET_CAUSE_REG RTC_CNTL_STORE6_REG +#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG /* FAST_RTC_MEMORY_CRC */ + /**************************************************************************** * Private Types ****************************************************************************/ @@ -176,6 +201,28 @@ struct esp32_rtc_sleep_pd_config_s uint32_t fe_pd : 1; /* Set to 1 to power down WiFi in sleep */ }; +#ifdef CONFIG_RTC_DRIVER + +#ifdef CONFIG_RTC_ALARM +struct alm_cbinfo_s +{ + struct rt_timer_s *alarm_hdl; /* Timer id point to here */ + volatile alm_callback_t ac_cb; /* Client callback function */ + volatile FAR void *ac_arg; /* Argument to pass with the callback function */ + uint64_t deadline_us; + uint8_t index; +}; +#endif + +struct esp32_rtc_backup_s +{ + uint64_t magic; + int64_t offset; /* Offset time from RTC HW value */ + int64_t reserved0; +}; + +#endif + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -191,6 +238,10 @@ static void IRAM_ATTR esp32_rtc_clk_slow_freq_set( enum esp32_rtc_slow_freq_e slow_freq); static void esp32_select_rtc_slow_clk(enum esp32_slow_clk_sel_e slow_clk); +#ifdef CONFIG_RTC_DRIVER +static void IRAM_ATTR esp32_rt_cb_handler(FAR void *arg); +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -205,6 +256,31 @@ static struct esp32_rtc_priv_s esp32_rtc_priv = .rtc_dboost_fpd = 1 }; +#ifdef CONFIG_RTC_DRIVER + +/* Callback to use when the alarm expires */ + +#ifdef CONFIG_RTC_ALARM +static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST]; +#endif + +static RTC_DATA_ATTR struct esp32_rtc_backup_s rtc_saved_data; + +/* Saved data for persistent RTC time */ + +static struct esp32_rtc_backup_s *g_rtc_save; +static bool g_rt_timer_enabled = false; + +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef CONFIG_RTC_DRIVER +volatile bool g_rtc_enabled = false; +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -475,6 +551,49 @@ static void esp32_select_rtc_slow_clk(enum esp32_slow_clk_sel_e slow_clk) putreg32((uint32_t)cal_val, RTC_SLOW_CLK_CAL_REG); } +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Name: esp32_rt_cb_handler + * + * Description: + * RT-Timer service routine + * + * Input Parameters: + * arg - Information about the RT-Timer configuration. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR esp32_rt_cb_handler(FAR void *arg) +{ + FAR struct alm_cbinfo_s *cbinfo = (struct alm_cbinfo_s *)arg; + alm_callback_t cb; + FAR void *cb_arg; + int alminfo_id; + + DEBUGASSERT(cbinfo != NULL); + alminfo_id = cbinfo->index; + DEBUGASSERT((RTC_ALARM0 <= alminfo_id) && + (alminfo_id < RTC_ALARM_LAST)); + + if (cbinfo->ac_cb != NULL) + { + /* Alarm callback */ + + cb = cbinfo->ac_cb; + cb_arg = (FAR void *)cbinfo->ac_arg; + cbinfo->ac_cb = NULL; + cbinfo->ac_arg = NULL; + cbinfo->deadline_us = 0; + cb(cb_arg, alminfo_id); + } +} + +#endif /* CONFIG_RTC_DRIVER */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -826,7 +945,7 @@ void IRAM_ATTR esp32_rtc_bbpll_configure( * ****************************************************************************/ -void esp32_rtc_clk_set() +void esp32_rtc_clk_set(void) { enum esp32_rtc_fast_freq_e fast_freq = RTC_FAST_FREQ_8M; enum esp32_slow_clk_sel_e slow_clk = RTC_SLOW_FREQ_RTC; @@ -848,7 +967,7 @@ void esp32_rtc_clk_set() * ****************************************************************************/ -void IRAM_ATTR esp32_rtc_init() +void IRAM_ATTR esp32_rtc_init(void) { struct esp32_rtc_priv_s *priv = &esp32_rtc_priv; @@ -1473,3 +1592,471 @@ int IRAM_ATTR esp32_rtc_sleep_start(uint32_t wakeup_opt, RTC_CNTL_DBG_ATTEN_DEFAULT); return reject; } + +/**************************************************************************** + * Name: esp32_rtc_get_time_us + * + * Description: + * Get current value of RTC counter in microseconds + * + * Input Parameters: + * None + * + * Returned Value: + * Current value of RTC counter in microseconds + * + ****************************************************************************/ + +uint64_t esp32_rtc_get_time_us(void) +{ + const uint32_t cal = getreg32(RTC_SLOW_CLK_CAL_REG); + const uint64_t rtc_this_ticks = esp32_rtc_time_get(); + + /* RTC counter result is up to 2^48, calibration factor is up to 2^24, + * for a 32kHz clock. We need to calculate (assuming no overflow): + * (ticks * cal) >> RTC_CLK_CAL_FRACT. An overflow in the (ticks * cal) + * multiplication would cause time to wrap around after approximately + * 13 days, which is probably not enough for some applications. + * Therefore multiplication is split into two terms, for the lower 32-bit + * and the upper 16-bit parts of "ticks", i.e.: + * ((ticks_low + 2^32 * ticks_high) * cal) >> RTC_CLK_CAL_FRACT + */ + + const uint64_t ticks_low = rtc_this_ticks & UINT32_MAX; + const uint64_t ticks_high = rtc_this_ticks >> 32; + const uint64_t delta_time_us = ((ticks_low * cal) >> RTC_CLK_CAL_FRACT) + + ((ticks_high * cal) << (32 - RTC_CLK_CAL_FRACT)); + + return delta_time_us; +} + +/**************************************************************************** + * Name: esp32_rtc_set_boot_time + * + * Description: + * Set time to RTC register to replace the original boot time. + * + * Input Parameters: + * time_us - set time in microseconds. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp32_rtc_set_boot_time(uint64_t time_us) +{ + putreg32((uint32_t)(time_us & UINT32_MAX), RTC_BOOT_TIME_LOW_REG); + putreg32((uint32_t)(time_us >> 32), RTC_BOOT_TIME_HIGH_REG); +} + +/**************************************************************************** + * Name: esp32_rtc_get_boot_time + * + * Description: + * Get time of RTC register to indicate the original boot time. + * + * Input Parameters: + * None + * + * Returned Value: + * time_us - get time in microseconds. + * + ****************************************************************************/ + +uint64_t IRAM_ATTR esp32_rtc_get_boot_time(void) +{ + return ((uint64_t)getreg32(RTC_BOOT_TIME_LOW_REG)) + + (((uint64_t)getreg32(RTC_BOOT_TIME_HIGH_REG)) << 32); +} + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Name: up_rtc_time + * + * Description: + * Get the current time in seconds. This is similar to the standard time() + * function. This interface is only required if the low-resolution + * RTC/counter hardware implementation is selected. It is only used by the + * RTOS during initialization to set up the system time when CONFIG_RTC is + * set but CONFIG_RTC_HIRES is not set. + * + * Input Parameters: + * None + * + * Returned Value: + * The current time in seconds + * + ****************************************************************************/ + +#ifndef CONFIG_RTC_HIRES +time_t up_rtc_time(void) +{ + uint64_t time_us; + irqstate_t flags; + + flags = spin_lock_irqsave(NULL); + + /* NOTE: RT-Timer starts to work after the board is initialized, and the + * RTC controller starts works after up_rtc_initialize is initialized. + * Since the system clock starts to work before the board is initialized, + * if CONFIG_RTC is enabled, the system time must be matched by the time + * of the RTC controller (up_rtc_initialize has already been initialized, + * and RT-Timer cannot work). + */ + + /* Determine if RT-Timer is started */ + + if (g_rt_timer_enabled == true) + { + /* Get the time from RT-Timer, the time interval between RTC + * controller and RT-Timer is stored in g_rtc_save->offset. + */ + + time_us = rt_timer_time_us() + g_rtc_save->offset + + esp32_rtc_get_boot_time(); + } + else + { + /* Get the time from RTC controller. */ + + time_us = esp32_rtc_get_time_us() + + esp32_rtc_get_boot_time(); + } + + spin_unlock_irqrestore(NULL, flags); + + return (time_t)(time_us / USEC_PER_SEC); +} +#endif /* !CONFIG_RTC_HIRES */ + +/**************************************************************************** + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be + * able to set their time based on a standard timespec. + * + * Input Parameters: + * ts - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *ts) +{ + irqstate_t flags; + uint64_t now_us; + uint64_t rtc_offset_us; + + DEBUGASSERT(ts != NULL && ts->tv_nsec < NSEC_PER_SEC); + flags = spin_lock_irqsave(NULL); + + now_us = ((uint64_t) ts->tv_sec) * USEC_PER_SEC + + ts->tv_nsec / NSEC_PER_USEC; + if (g_rt_timer_enabled == true) + { + /* Set based on RT-Timer offset value. */ + + rtc_offset_us = now_us - rt_timer_time_us(); + } + else + { + /* Set based on the offset value of the RT controller. */ + + rtc_offset_us = now_us - esp32_rtc_get_time_us(); + } + + g_rtc_save->offset = 0; + esp32_rtc_set_boot_time(rtc_offset_us); + + spin_unlock_irqrestore(NULL, flags); + + return OK; +} + +/**************************************************************************** + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. + * This function is called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_initialize(void) +{ +#ifndef CONFIG_PM + /* Initialize RTC controller parameters */ + + esp32_rtc_init(); + esp32_rtc_clk_set(); +#endif + + g_rtc_save = &rtc_saved_data; + + /* If saved data is invalid, clear offset information */ + + if (g_rtc_save->magic != MAGIC_RTC_SAVE) + { + g_rtc_save->magic = MAGIC_RTC_SAVE; + g_rtc_save->offset = 0; + esp32_rtc_set_boot_time(0); + } + +#ifdef CONFIG_RTC_HIRES + /* Synchronize the base time to the RTC time */ + + up_rtc_gettime(&g_basetime); +#endif + + g_rtc_enabled = true; + + return OK; +} + +/**************************************************************************** + * Name: up_rtc_gettime + * + * Description: + * Get the current time from the high resolution RTC time or RT-Timer. This + * interface is only supported by the high-resolution RTC/counter hardware + * implementation. It is used to replace the system timer. + * + * Input Parameters: + * tp - The location to return the RTC time or RT-Timer value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_HIRES +int up_rtc_gettime(FAR struct timespec *tp) +{ + irqstate_t flags; + uint64_t time_us; + + flags = spin_lock_irqsave(NULL); + + if (g_rt_timer_enabled == true) + { + time_us = rt_timer_time_us() + g_rtc_save->offset + + esp32_rtc_get_boot_time(); + } + else + { + time_us = = esp32_rtc_get_time_us() + + esp32_rtc_get_boot_time(); + } + + tp->tv_sec = time_us / USEC_PER_SEC; + tp->tv_nsec = (time_us % USEC_PER_SEC) * NSEC_PER_USEC; + + spin_unlock_irqrestore(NULL, flags); + + return OK; +} +#endif /* CONFIG_RTC_HIRES */ + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Name: up_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * alminfo - Information about the alarm configuration. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_setalarm(FAR struct alm_setalarm_s *alminfo) +{ + struct rt_timer_args_s rt_timer_args; + FAR struct alm_cbinfo_s *cbinfo; + irqstate_t flags; + int ret = -EBUSY; + int id; + + DEBUGASSERT(alminfo != NULL); + DEBUGASSERT((RTC_ALARM0 <= alminfo->as_id) && + (alminfo->as_id < RTC_ALARM_LAST)); + + /* Set the alarm in RT-Timer */ + + id = alminfo->as_id; + cbinfo = &g_alarmcb[id]; + + if (cbinfo->ac_cb == NULL) + { + /* Create the RT-Timer alarm */ + + flags = spin_lock_irqsave(NULL); + + if (cbinfo->alarm_hdl == NULL) + { + cbinfo->index = id; + rt_timer_args.arg = cbinfo; + rt_timer_args.callback = esp32_rt_cb_handler; + ret = rt_timer_create(&rt_timer_args, &cbinfo->alarm_hdl); + if (ret < 0) + { + rtcerr("ERROR: Failed to create rt_timer error=%d\n", ret); + spin_unlock_irqrestore(NULL, flags); + return ret; + } + } + + cbinfo->ac_cb = alminfo->as_cb; + cbinfo->ac_arg = alminfo->as_arg; + cbinfo->deadline_us = alminfo->as_time.tv_sec * USEC_PER_SEC + + alminfo->as_time.tv_nsec / NSEC_PER_USEC; + + if (cbinfo->alarm_hdl == NULL) + { + rtcerr("ERROR: failed to create alarm timer\n"); + } + else + { + rtcinfo("Start RTC alarm.\n"); + rt_timer_start(cbinfo->alarm_hdl, cbinfo->deadline_us, false); + ret = OK; + } + + spin_unlock_irqrestore(NULL, flags); + } + + return ret; +} + +/**************************************************************************** + * Name: up_rtc_cancelalarm + * + * Description: + * Cancel an alarm. + * + * Input Parameters: + * alarmid - Identifies the alarm to be cancelled + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_cancelalarm(enum alm_id_e alarmid) +{ + FAR struct alm_cbinfo_s *cbinfo; + irqstate_t flags; + int ret = -ENODATA; + + DEBUGASSERT((RTC_ALARM0 <= alarmid) && + (alarmid < RTC_ALARM_LAST)); + + /* Set the alarm in hardware and enable interrupts */ + + cbinfo = &g_alarmcb[alarmid]; + + if (cbinfo->ac_cb != NULL) + { + flags = spin_lock_irqsave(NULL); + + /* Stop and delete the alarm */ + + rtcinfo("Cancel RTC alarm.\n"); + rt_timer_stop(cbinfo->alarm_hdl); + rt_timer_delete(cbinfo->alarm_hdl); + cbinfo->ac_cb = NULL; + cbinfo->deadline_us = 0; + cbinfo->alarm_hdl = NULL; + + spin_unlock_irqrestore(NULL, flags); + + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: up_rtc_rdalarm + * + * Description: + * Query an alarm configured in hardware. + * + * Input Parameters: + * tp - Location to return the timer match register. + * alarmid - Identifies the alarm to get. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_rdalarm(FAR struct timespec *tp, uint32_t alarmid) +{ + irqstate_t flags; + FAR struct alm_cbinfo_s *cbinfo; + DEBUGASSERT(tp != NULL); + DEBUGASSERT((RTC_ALARM0 <= alarmid) && + (alarmid < RTC_ALARM_LAST)); + + flags = spin_lock_irqsave(NULL); + + /* Get the alarm according to the alarmid */ + + cbinfo = &g_alarmcb[alarmid]; + + tp->tv_sec = (rt_timer_time_us() + g_rtc_save->offset + + cbinfo->deadline_us) / USEC_PER_SEC; + tp->tv_nsec = ((rt_timer_time_us() + g_rtc_save->offset + + cbinfo->deadline_us) % USEC_PER_SEC) * NSEC_PER_USEC; + + spin_unlock_irqrestore(NULL, flags); + + return OK; +} + +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: up_rtc_timer_init + * + * Description: + * Init RTC timer. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_timer_init(void) +{ + /* RT-Timer enabled */ + + g_rt_timer_enabled = true; + + /* Get the time difference between rt_timer and RTC timer */ + + g_rtc_save->offset = esp32_rtc_get_time_us() - rt_timer_time_us(); + + return OK; +} + +#endif /* CONFIG_RTC_DRIVER */ \ No newline at end of file diff --git a/arch/xtensa/src/esp32/esp32_rtc.h b/arch/xtensa/src/esp32/esp32_rtc.h index 025c8784efe..3ce469b5dfa 100644 --- a/arch/xtensa/src/esp32/esp32_rtc.h +++ b/arch/xtensa/src/esp32/esp32_rtc.h @@ -30,6 +30,9 @@ ****************************************************************************/ #include +#include +#include +#include #include "hardware/esp32_soc.h" #ifndef __ASSEMBLY__ @@ -127,6 +130,31 @@ enum esp32_rtc_cal_sel_e RTC_CAL_32K_XTAL = 2 /* External 32 kHz XTAL */ }; +#ifdef CONFIG_RTC_ALARM + +/* The form of an alarm callback */ + +typedef CODE void (*alm_callback_t)(FAR void *arg, unsigned int alarmid); + +enum alm_id_e +{ + RTC_ALARM0 = 0, /* RTC ALARM 0 */ + RTC_ALARM1 = 1, /* RTC ALARM 1 */ + RTC_ALARM_LAST, +}; + +/* Structure used to pass parameters to set an alarm */ + +struct alm_setalarm_s +{ + int as_id; /* enum alm_id_e */ + struct timespec as_time; /* Alarm expiration time */ + alm_callback_t as_cb; /* Callback (if non-NULL) */ + FAR void *as_arg; /* Argument for callback */ +}; + +#endif /* CONFIG_RTC_ALARM */ + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -447,6 +475,203 @@ void esp32_rtc_sleep_init(uint32_t flags); int esp32_rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt); +/**************************************************************************** + * Name: esp32_rtc_get_time_us + * + * Description: + * Get current value of RTC counter in microseconds + * + * Input Parameters: + * None + * + * Returned Value: + * Current value of RTC counter in microseconds + * + ****************************************************************************/ + +uint64_t esp32_rtc_get_time_us(void); + +/**************************************************************************** + * Name: esp32_rtc_set_boot_time + * + * Description: + * Set time to RTC register to replace the original boot time. + * + * Input Parameters: + * time_us - set time in microseconds. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp32_rtc_set_boot_time(uint64_t time_us); + +/**************************************************************************** + * Name: esp32_rtc_get_boot_time + * + * Description: + * Get time of RTC register to indicate the original boot time. + * + * Input Parameters: + * None + * + * Returned Value: + * time_us - get time in microseconds. + * + ****************************************************************************/ + +uint64_t esp32_rtc_get_boot_time(void); + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Name: up_rtc_time + * + * Description: + * Get the current time in seconds. This is similar to the standard time() + * function. This interface is only required if the low-resolution + * RTC/counter hardware implementation selected. It is only used by the + * RTOS during initialization to set up the system time when CONFIG_RTC is + * set but neither CONFIG_RTC_HIRES nor CONFIG_RTC_DATETIME are set. + * + * Input Parameters: + * None + * + * Returned Value: + * The current time in seconds + * + ****************************************************************************/ + +#ifndef CONFIG_RTC_HIRES +time_t up_rtc_time(void); +#endif + +/**************************************************************************** + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be + * able to set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *ts); + +/**************************************************************************** + * Name: up_rtc_initialize + * + * Description: + * Initialize the hardware RTC per the selected configuration. + * This function is called once during the OS initialization sequence + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_initialize(void); + +/**************************************************************************** + * Name: up_rtc_gettime + * + * Description: + * Get the current time from the high resolution RTC clock/counter. This + * interface is only supported by the high-resolution RTC/counter hardware + * implementation. It is used to replace the system timer. + * + * Input Parameters: + * tp - The location to return the high resolution time value. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_HIRES +int up_rtc_gettime(FAR struct timespec *tp); +#endif + +#ifdef CONFIG_RTC_ALARM + +/**************************************************************************** + * Name: up_rtc_setalarm + * + * Description: + * Set up an alarm. + * + * Input Parameters: + * alminfo - Information about the alarm configuration. + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_setalarm(FAR struct alm_setalarm_s *alminfo); + +/**************************************************************************** + * Name: up_rtc_cancelalarm + * + * Description: + * Cancel an alaram. + * + * Input Parameters: + * alarmid - Identifies the alarm to be cancelled + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_cancelalarm(enum alm_id_e alarmid); + +/**************************************************************************** + * Name: up_rtc_rdalarm + * + * Description: + * Query an alarm configured in hardware. + * + * Input Parameters: + * tp - Location to return the timer match register. + * alarmid - Identifies the alarm to be cancelled + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_rdalarm(FAR struct timespec *tp, uint32_t alarmid); + +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: up_rtc_timer_init + * + * Description: + * Init RTC timer. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ****************************************************************************/ + +int up_rtc_timer_init(void); + +#endif /* CONFIG_RTC_DRIVER */ + #ifdef __cplusplus } #endif diff --git a/arch/xtensa/src/esp32/esp32_rtc_lowerhalf.c b/arch/xtensa/src/esp32/esp32_rtc_lowerhalf.c new file mode 100644 index 00000000000..e2ca2edb973 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_rtc_lowerhalf.c @@ -0,0 +1,565 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_rtc_lowerhalf.c + * + * 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 "esp32_rtc.h" +#include "hardware/esp32_tim.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +struct esp32_cbinfo_s +{ + volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */ + volatile FAR void *priv; /* Private argurment to accompany callback */ +}; +#endif + +/* This is the private type for the RTC state. It must be cast compatible + * with struct rtc_lowerhalf_s. + */ + +struct esp32_lowerhalf_s +{ + /* This is the contained reference to the read-only, lower-half + * operations vtable (which may lie in FLASH or ROM) + */ + + FAR const struct rtc_ops_s *ops; +#ifdef CONFIG_RTC_ALARM + /* Alarm callback information */ + + struct esp32_cbinfo_s cbinfo[RTC_ALARM_LAST]; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Prototypes for static methods in struct rtc_ops_s */ + +static int rtc_lh_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime); +static int rtc_lh_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime); +static bool rtc_lh_havesettime(FAR struct rtc_lowerhalf_s *lower); + +#ifdef CONFIG_RTC_ALARM +static void rtc_lh_alarm_callback(FAR void *arg, unsigned int alarmid); +static int rtc_lh_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo); +static int rtc_lh_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *alarminfo); +static int rtc_lh_cancelalarm(FAR struct rtc_lowerhalf_s *lower, + int alarmid); +static int rtc_lh_rdalarm(FAR struct rtc_lowerhalf_s *lower, + FAR struct lower_rdalarm_s *alarminfo); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ESP32 RTC driver operations */ + +static const struct rtc_ops_s g_rtc_ops = +{ + .rdtime = rtc_lh_rdtime, + .settime = rtc_lh_settime, + .havesettime = rtc_lh_havesettime, +#ifdef CONFIG_RTC_ALARM + .setalarm = rtc_lh_setalarm, + .setrelative = rtc_lh_setrelative, + .cancelalarm = rtc_lh_cancelalarm, + .rdalarm = rtc_lh_rdalarm, +#endif +#ifdef CONFIG_RTC_PERIODIC + .setperiodic = NULL, + .cancelperiodic = NULL, +#endif +#ifdef CONFIG_RTC_IOCTL + .ioctl = NULL, +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + .destroy = NULL, +#endif +}; + +/* ESP32 RTC device state */ + +static struct esp32_lowerhalf_s g_rtc_lowerhalf = +{ + .ops = &g_rtc_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rtc_lh_alarm_callback + * + * Description: + * This is the function that is called from the RTC driver when the alarm + * goes off. It just invokes the upper half drivers callback. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static void rtc_lh_alarm_callback(FAR void *arg, unsigned int alarmid) +{ + FAR struct esp32_lowerhalf_s *lower; + FAR struct esp32_cbinfo_s *cbinfo; + rtc_alarm_callback_t cb; + FAR void *priv; + + DEBUGASSERT((RTC_ALARM0 <= alarmid) && (alarmid < RTC_ALARM_LAST)); + + lower = (struct esp32_lowerhalf_s *)arg; + cbinfo = &lower->cbinfo[alarmid]; + + /* Sample and clear the callback information to minimize the window in + * time in which race conditions can occur. + */ + + cb = (rtc_alarm_callback_t)cbinfo->cb; + priv = (FAR void *)cbinfo->priv; + + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Perform the callback */ + + if (cb != NULL) + { + cb(priv, alarmid); + } +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rtc_lh_rdtime + * + * Description: + * Returns the current RTC time. + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The location in which to return the current RTC time. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int rtc_lh_rdtime(FAR struct rtc_lowerhalf_s *lower, + FAR struct rtc_time *rtctime) +{ +#if defined(CONFIG_RTC_HIRES) + FAR struct timespec ts; + int ret; + + /* Get the higher resolution time */ + + ret = up_rtc_gettime(&ts); + if (ret < 0) + { + goto errout; + } + + /* Convert the one second epoch time to a struct tm. This operation + * depends on the fact that struct rtc_time and struct tm are cast + * compatible. + */ + + if (!gmtime_r(&ts.tv_sec, (FAR struct tm *)rtctime)) + { + ret = -get_errno(); + goto errout; + } + + return OK; + +errout: + rtcerr("ERROR: failed to get RTC time: %d\n", ret); + return ret; + +#else + time_t timer; + + /* The resolution of time is only 1 second */ + + timer = up_rtc_time(); + + /* Convert the one second epoch time to a struct tm */ + + if (gmtime_r(&timer, (FAR struct tm *)rtctime) == 0) + { + int errcode = get_errno(); + DEBUGASSERT(errcode > 0); + + rtcerr("ERROR: gmtime_r failed: %d\n", errcode); + return -errcode; + } + + return OK; +#endif +} + +/**************************************************************************** + * Name: rtc_lh_settime + * + * Description: + * Implements the settime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * rcttime - The new time to set + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +static int rtc_lh_settime(FAR struct rtc_lowerhalf_s *lower, + FAR const struct rtc_time *rtctime) +{ + struct timespec ts; + + /* Convert the struct rtc_time to a time_t. Here we assume that struct + * rtc_time is cast compatible with struct tm. + */ + + ts.tv_sec = mktime((FAR struct tm *)rtctime); + ts.tv_nsec = 0; + + /* Now set the time (with a accuracy of seconds) */ + + return up_rtc_settime(&ts); +} + +/**************************************************************************** + * Name: rtc_lh_havesettime + * + * Description: + * Implements the havesettime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ****************************************************************************/ + +static bool rtc_lh_havesettime(FAR struct rtc_lowerhalf_s *lower) +{ + if (esp32_rtc_get_boot_time() == 0) + { + return false; + } + + return true; +} + +/**************************************************************************** + * Name: rtc_lh_setalarm + * + * Description: + * Set a new alarm. This function implements the setalarm() method of the + * RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to set the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_lh_setalarm(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setalarm_s *alarminfo) +{ + FAR struct esp32_lowerhalf_s *priv; + FAR struct esp32_cbinfo_s *cbinfo; + struct alm_setalarm_s lowerinfo; + int ret; + + DEBUGASSERT(lower != NULL && alarminfo != NULL); + DEBUGASSERT((RTC_ALARM0 <= alarminfo->id) && + (alarminfo->id < RTC_ALARM_LAST)); + + priv = (FAR struct esp32_lowerhalf_s *)lower; + + /* Remember the callback information */ + + cbinfo = &priv->cbinfo[alarminfo->id]; + cbinfo->cb = alarminfo->cb; + cbinfo->priv = alarminfo->priv; + + /* Set the alarm */ + + lowerinfo.as_id = alarminfo->id; + lowerinfo.as_cb = rtc_lh_alarm_callback; + lowerinfo.as_arg = priv; + + /* Convert the RTC time to a timespec (1 second accuracy) */ + + lowerinfo.as_time.tv_sec = mktime((FAR struct tm *)&alarminfo->time); + lowerinfo.as_time.tv_nsec = 0; + + /* And set the alarm */ + + ret = up_rtc_setalarm(&lowerinfo); + if (ret < 0) + { + cbinfo->cb = NULL; + cbinfo->priv = NULL; + } + + return ret; +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rtc_lh_setrelative + * + * Description: + * Set a new alarm relative to the current time. This function implements + * the setrelative() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to set the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_lh_setrelative(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *alarminfo) +{ + struct lower_setalarm_s setalarm; + time_t seconds; + int ret = -EINVAL; + irqstate_t flags; + + DEBUGASSERT(lower != NULL && alarminfo != NULL); + DEBUGASSERT((RTC_ALARM0 <= alarminfo->id) && + (alarminfo->id < RTC_ALARM_LAST)); + + if (alarminfo->reltime > 0) + { + flags = spin_lock_irqsave(NULL); + + seconds = alarminfo->reltime; + gmtime_r(&seconds, (FAR struct tm *)&setalarm.time); + + /* The set the alarm using this absolute time */ + + setalarm.id = alarminfo->id; + setalarm.cb = alarminfo->cb; + setalarm.priv = alarminfo->priv; + ret = rtc_lh_setalarm(lower, &setalarm); + + spin_unlock_irqrestore(NULL, flags); + } + + return ret; +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rtc_lh_cancelalarm + * + * Description: + * Cancel the current alarm. This function implements the cancelalarm() + * method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarmid - the alarm id + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_lh_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid) +{ + FAR struct esp32_lowerhalf_s *priv; + FAR struct esp32_cbinfo_s *cbinfo; + + DEBUGASSERT(lower != NULL); + DEBUGASSERT((RTC_ALARM0 <= alarmid) && (alarmid < RTC_ALARM_LAST)); + + priv = (FAR struct esp32_lowerhalf_s *)lower; + + /* Nullify callback information to reduce window for race conditions */ + + cbinfo = &priv->cbinfo[alarmid]; + cbinfo->cb = NULL; + cbinfo->priv = NULL; + + /* Then cancel the alarm */ + + return up_rtc_cancelalarm((enum alm_id_e)alarmid); +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Name: rtc_lh_rdalarm + * + * Description: + * Query the RTC alarm. + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * alarminfo - Provided information needed to query the alarm + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_ALARM +static int rtc_lh_rdalarm(FAR struct rtc_lowerhalf_s *lower, + FAR struct lower_rdalarm_s *alarminfo) +{ + struct timespec ts; + int ret; + irqstate_t flags; + + DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->time != NULL); + DEBUGASSERT((RTC_ALARM0 <= alarminfo->id) && + (alarminfo->id < RTC_ALARM_LAST)); + + flags = spin_lock_irqsave(NULL); + + ret = up_rtc_rdalarm(&ts, alarminfo->id); + localtime_r((FAR const time_t *)&ts.tv_sec, + (FAR struct tm *)alarminfo->time); + + spin_unlock_irqrestore(NULL, flags); + + return ret; +} +#endif /* CONFIG_RTC_ALARM */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the ESP32. + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +FAR struct rtc_lowerhalf_s *esp32_rtc_lowerhalf(void) +{ + return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf; +} + +/**************************************************************************** + * Name: esp32_rtc_driverinit + * + * Description: + * Bind the configuration timer to a timer lower half instance and register + * the timer drivers at 'devpath' + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int esp32_rtc_driverinit(void) +{ + int ret; + FAR struct rtc_lowerhalf_s *lower; + + /* Instantiate the ESP32 lower-half RTC driver */ + + lower = esp32_rtc_lowerhalf(); + if (lower == NULL) + { + return ret; + } + else + { + /* Bind the lower half driver and register the combined RTC driver + * as /dev/rtc0 + */ + + ret = rtc_initialize(0, lower); + } + + /* Init RTC timer */ + + up_rtc_timer_init(); + + return ret; +} diff --git a/arch/xtensa/src/esp32/esp32_rtc_lowerhalf.h b/arch/xtensa/src/esp32/esp32_rtc_lowerhalf.h new file mode 100644 index 00000000000..a5ef77ed98d --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_rtc_lowerhalf.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_rtc_lowerhalf.h + * + * 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_XTENSA_SRC_ESP32_ESP32_RTC_LOWERHALF_H +#define __ARCH_XTENSA_SRC_ESP32_ESP32_RTC_LOWERHALF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_rtc_driverinit + * + * Description: + * Bind the configuration timer to a timer lower half instance and register + * the timer drivers at 'devpath' + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int esp32_rtc_driverinit(void); + +#endif /* CONFIG_RTC_DRIVER */ + +#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_RTC_LOWERHALF_H */ diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/rtc/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/rtc/defconfig new file mode 100644 index 00000000000..da3516788e5 --- /dev/null +++ b/boards/xtensa/esp32/esp32-devkitc/configs/rtc/defconfig @@ -0,0 +1,53 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32-devkitc" +CONFIG_ARCH_BOARD_ESP32_DEVKITC=y +CONFIG_ARCH_CHIP="esp32" +CONFIG_ARCH_CHIP_ESP32=y +CONFIG_ARCH_CHIP_ESP32WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_ESP32_RT_TIMER=y +CONFIG_ESP32_UART0=y +CONFIG_EXAMPLES_ALARM=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_MAX_TASKS=16 +CONFIG_MM_REGIONS=3 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RTC=y +CONFIG_RTC_ALARM=y +CONFIG_RTC_DRIVER=y +CONFIG_RTC_NALARMS=2 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c index 75a61dad129..ca844a6c3ab 100644 --- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c @@ -90,6 +90,10 @@ # include #endif +#ifdef CONFIG_RTC_DRIVER +# include "esp32_rtc_lowerhalf.h" +#endif + #include "esp32-devkitc.h" /**************************************************************************** @@ -375,6 +379,17 @@ int esp32_bringup(void) } #endif +#ifdef CONFIG_RTC_DRIVER + /* Instantiate the ESP32 RTC driver */ + + ret = esp32_rtc_driverinit(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to Instantiate the RTC driver: %d\n", ret); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities. diff --git a/boards/xtensa/esp32/esp32-ethernet-kit/configs/rtc/defconfig b/boards/xtensa/esp32/esp32-ethernet-kit/configs/rtc/defconfig new file mode 100644 index 00000000000..ec058628dbb --- /dev/null +++ b/boards/xtensa/esp32/esp32-ethernet-kit/configs/rtc/defconfig @@ -0,0 +1,52 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32-ethernet-kit" +CONFIG_ARCH_BOARD_ESP32_ETHERNETKIT=y +CONFIG_ARCH_CHIP="esp32" +CONFIG_ARCH_CHIP_ESP32=y +CONFIG_ARCH_CHIP_ESP32WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_ESP32_RT_TIMER=y +CONFIG_ESP32_UART0=y +CONFIG_EXAMPLES_ALARM=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_MAX_TASKS=16 +CONFIG_MM_REGIONS=3 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RTC=y +CONFIG_RTC_ALARM=y +CONFIG_RTC_DRIVER=y +CONFIG_RTC_NALARMS=2 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c index 20b33092a71..e1875b5e41c 100644 --- a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c @@ -70,6 +70,10 @@ # include #endif +#ifdef CONFIG_RTC_DRIVER +# include "esp32_rtc_lowerhalf.h" +#endif + #include "esp32-ethernet-kit.h" /**************************************************************************** @@ -271,6 +275,17 @@ int esp32_bringup(void) } #endif +#ifdef CONFIG_RTC_DRIVER + /* Instantiate the ESP32 RTC driver */ + + ret = esp32_rtc_driverinit(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to Instantiate the RTC driver: %d\n", ret); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities. diff --git a/boards/xtensa/esp32/esp32-wrover-kit/configs/rtc/defconfig b/boards/xtensa/esp32/esp32-wrover-kit/configs/rtc/defconfig new file mode 100644 index 00000000000..4d87cf856b0 --- /dev/null +++ b/boards/xtensa/esp32/esp32-wrover-kit/configs/rtc/defconfig @@ -0,0 +1,53 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32-wrover-kit" +CONFIG_ARCH_BOARD_ESP32_WROVERKIT=y +CONFIG_ARCH_CHIP="esp32" +CONFIG_ARCH_CHIP_ESP32=y +CONFIG_ARCH_CHIP_ESP32WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_ESP32_RT_TIMER=y +CONFIG_ESP32_UART0=y +CONFIG_EXAMPLES_ALARM=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_MAX_TASKS=16 +CONFIG_MM_REGIONS=3 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RTC=y +CONFIG_RTC_ALARM=y +CONFIG_RTC_DRIVER=y +CONFIG_RTC_NALARMS=2 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_NSH=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c index 5012d2e751c..a9ee883427a 100644 --- a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c @@ -90,6 +90,10 @@ # include #endif +#ifdef CONFIG_RTC_DRIVER +# include "esp32_rtc_lowerhalf.h" +#endif + #include "esp32-wrover-kit.h" /**************************************************************************** @@ -358,6 +362,17 @@ int esp32_bringup(void) } #endif +#ifdef CONFIG_RTC_DRIVER + /* Instantiate the ESP32 RTC driver */ + + ret = esp32_rtc_driverinit(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to Instantiate the RTC driver: %d\n", ret); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities.