diff --git a/arch/xtensa/src/common/xtensa_counter.h b/arch/xtensa/src/common/xtensa_counter.h new file mode 100644 index 00000000000..3228459cb6d --- /dev/null +++ b/arch/xtensa/src/common/xtensa_counter.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * arch/xtensa/src/common/xtensa_counter.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_COMMON_XTENSA_COUNTER_H +#define __ARCH_XTENSA_SRC_COMMON_XTENSA_COUNTER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "xtensa_timer.h" + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Name: xtensa_getcount + * + * Description: + * Get the current value of the cycle count register. + * + ****************************************************************************/ + +static inline uint32_t xtensa_getcount(void) +{ + uint32_t count; + + __asm__ __volatile__ + ( + "rsr %0, CCOUNT" : "=r"(count) + ); + + return count; +} + +/**************************************************************************** + * Name: xtensa_setcount + * + * Description: + * Set the value of the cycle count register. + * + ****************************************************************************/ + +static inline void xtensa_setcount(uint32_t ticks) +{ + __asm__ __volatile__ + ( + "wsr %0, ccount\n" + : + : "a"(ticks) + : "memory" + ); +} + +/**************************************************************************** + * Name: xtensa_getcompare + * + * Description: + * Get the old value of the compare register. + * + ****************************************************************************/ + +static inline uint32_t xtensa_getcompare(void) +{ + uint32_t compare; + + __asm__ __volatile__ + ( + "rsr %0, %1" : "=r"(compare) : "I"(XT_CCOMPARE) + ); + + return compare; +} + +/**************************************************************************** + * Name: xtensa_getcompare + * + * Description: + * Set the value of the compare register. + * + ****************************************************************************/ + +static inline void xtensa_setcompare(uint32_t compare) +{ + __asm__ __volatile__ + ( + "wsr %0, %1" : : "r"(compare), "I"(XT_CCOMPARE) + ); +} + +#endif /* __ARCH_XTENSA_SRC_COMMON_XTENSA_COUNTER_H */ diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index f5e14fff49a..41065a2f4d2 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -972,17 +972,17 @@ config ESP32_WIFI_STA_DISCONNECT_PM Chip will do modem-sleep when RF module is not in use anymore. config EXAMPLE_WIFI_LISTEN_INTERVAL - int "WiFi listen interval" - default 3 - help + int "Wi-Fi listen interval" + default 3 + ---help--- Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval. For example, if beacon interval is 100 ms and listen interval is 3, the interval for station to listen to beacon is 300 ms. choice EXAMPLE_POWER_SAVE_MODE - prompt "power save mode" + prompt "Power save mode" default EXAMPLE_POWER_SAVE_NONE - help + ---help--- Power save mode for the esp32 to use. Modem sleep mode includes minimum and maximum power save modes. In minimum power save mode, station wakes up every DTIM to receive beacon. Broadcast data will not be lost because it is transmitted after DTIM. However, it can not save much more power if DTIM is short @@ -1074,7 +1074,7 @@ config ESP32_AUTO_SLEEP Enable ESP32 Auto-sleep config ESP32_TICKLESS - bool "Enable ESP32 tick-less OS" + bool "Enable ESP32 tickless OS" default n select ARCH_HAVE_TICKLESS select SCHED_TICKLESS diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index 5b26a3c0a45..69981bdb83b 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -78,10 +78,10 @@ CHIP_CSRCS += esp32_gpio.c esp32_intdecode.c esp32_irq.c esp32_region.c CHIP_CSRCS += esp32_user.c CHIP_CSRCS += esp32_dma.c -ifneq ($(CONFIG_SCHED_TICKLESS),y) -CHIP_CSRCS += esp32_timerisr.c -else +ifeq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += esp32_tickless.c +else +CHIP_CSRCS += esp32_timerisr.c endif ifeq ($(CONFIG_PM),y) diff --git a/arch/xtensa/src/esp32/esp32_idle.c b/arch/xtensa/src/esp32/esp32_idle.c index f2b09222e7b..0374f52579f 100644 --- a/arch/xtensa/src/esp32/esp32_idle.c +++ b/arch/xtensa/src/esp32/esp32_idle.c @@ -96,24 +96,20 @@ static void up_idlepm(void) irqstate_t flags; #ifdef CONFIG_ESP32_AUTO_SLEEP - uint64_t sleep_us; - uint64_t os_idle_us; - uint64_t os_start_us; - uint64_t os_end_us; - uint64_t os_step_us; - uint64_t hw_idle_us; - uint64_t hw_start_us; - uint64_t hw_end_us; - uint64_t hw_step_us; - uint64_t rtc_diff_us; - struct timespec ts; - flags = spin_lock_irqsave(NULL); if (esp32_pm_lockstatus() == 0) { - os_idle_us = up_get_idletime(); - hw_idle_us = rt_timer_get_alarm(); - sleep_us = MIN(os_idle_us, hw_idle_us); + uint64_t os_start_us; + uint64_t os_end_us; + uint64_t os_step_us; + uint64_t hw_start_us; + uint64_t hw_end_us; + uint64_t hw_step_us; + uint64_t rtc_diff_us; + struct timespec ts; + uint64_t os_idle_us = up_get_idletime(); + uint64_t hw_idle_us = rt_timer_get_alarm(); + uint64_t sleep_us = MIN(os_idle_us, hw_idle_us); if (sleep_us > EXPECTED_IDLE_TIME_US) { sleep_us -= EARLY_WAKEUP_US; diff --git a/arch/xtensa/src/esp32/esp32_pm.c b/arch/xtensa/src/esp32/esp32_pm.c index badae1daf44..3c4c5480fd3 100644 --- a/arch/xtensa/src/esp32/esp32_pm.c +++ b/arch/xtensa/src/esp32/esp32_pm.c @@ -200,7 +200,8 @@ static struct esp32_sleep_config_t s_config = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO }, .wakeup_triggers = 0 }; -static volatile uint32_t pm_wakelock = 0; + +static _Atomic uint32_t pm_wakelock = 0; /**************************************************************************** * Private Functions @@ -915,7 +916,7 @@ int esp32_light_sleep_start(uint64_t *sleep_time) ret = esp32_light_sleep_inner(pd_flags, flash_enable_time_us, vddsdio_config); - if (sleep_time) + if (sleep_time != NULL) { *sleep_time = esp32_rtc_time_slowclk_to_us(esp32_rtc_time_get() - s_config.rtc_ticks_at_sleep_start, esp32_clk_slowclk_cal_get()); @@ -997,7 +998,7 @@ void esp32_pmstandby(uint64_t time_in_us) up_step_idletime((uint32_t)time_in_us); #endif - pwrinfo("Returned from auto-sleep, slept for %d ms\n", + pwrinfo("Returned from auto-sleep, slept for %" PRIu32 " ms\n", (uint32_t)(rtc_diff_us) / 1000); } @@ -1140,11 +1141,7 @@ void esp32_pmsleep(uint64_t time_in_us) void IRAM_ATTR esp32_pm_lockacquire(void) { - irqstate_t flags; - - flags = enter_critical_section(); ++pm_wakelock; - leave_critical_section(flags); } /**************************************************************************** @@ -1157,11 +1154,7 @@ void IRAM_ATTR esp32_pm_lockacquire(void) void IRAM_ATTR esp32_pm_lockrelease(void) { - irqstate_t flags; - - flags = enter_critical_section(); --pm_wakelock; - leave_critical_section(flags); } /**************************************************************************** diff --git a/arch/xtensa/src/esp32/esp32_rtc.c b/arch/xtensa/src/esp32/esp32_rtc.c index 75f283214e8..0c4be46b58d 100644 --- a/arch/xtensa/src/esp32/esp32_rtc.c +++ b/arch/xtensa/src/esp32/esp32_rtc.c @@ -1017,8 +1017,8 @@ uint64_t IRAM_ATTR esp32_rtc_time_us_to_slowclk(uint64_t time_in_us, * Convert time interval from RTC_SLOW_CLK to microseconds * * Input Parameters: - * time_in_us - Time interval in RTC_SLOW_CLK cycles - * slow_clk_period - Period of slow clock in microseconds + * rtc_cycles - Time interval in RTC_SLOW_CLK cycles + * period - Period of slow clock in microseconds * * Returned Value: * Time interval in microseconds diff --git a/arch/xtensa/src/esp32/esp32_rtc.h b/arch/xtensa/src/esp32/esp32_rtc.h index 5c42d1a1b74..025c8784efe 100644 --- a/arch/xtensa/src/esp32/esp32_rtc.h +++ b/arch/xtensa/src/esp32/esp32_rtc.h @@ -308,8 +308,8 @@ uint64_t esp32_rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period); * Convert time interval from RTC_SLOW_CLK to microseconds * * Input Parameters: - * time_in_us - Time interval in RTC_SLOW_CLK cycles - * slow_clk_period - Period of slow clock in microseconds + * rtc_cycles - Time interval in RTC_SLOW_CLK cycles + * period - Period of slow clock in microseconds * * Returned Value: * Time interval in microseconds diff --git a/arch/xtensa/src/esp32/esp32_tickless.c b/arch/xtensa/src/esp32/esp32_tickless.c index 5d401003fe7..59f09d55dcd 100644 --- a/arch/xtensa/src/esp32/esp32_tickless.c +++ b/arch/xtensa/src/esp32/esp32_tickless.c @@ -62,6 +62,7 @@ #include "xtensa_timer.h" #include "xtensa.h" #include "xtensa_attr.h" +#include "xtensa_counter.h" #ifdef CONFIG_SCHED_TICKLESS @@ -74,6 +75,7 @@ #define SEC_2_CTICK(s) ((s) * CTICK_PER_SEC) #define USEC_2_CTICK(us) ((us) * CTICK_PER_USEC) +#define NSEC_2_CTICK(nsec) (((nsec) * CTICK_PER_USEC) / NSEC_PER_USEC) #define CTICK_2_SEC(tick) ((tick) / CTICK_PER_SEC) #define CTICK_2_USEC(tick) ((tick) / CTICK_PER_USEC) @@ -85,10 +87,6 @@ * Private Function Prototypes ****************************************************************************/ -static inline uint32_t xtensa_getcount(void); -static inline uint32_t xtensa_getcompare(void); -static inline void xtensa_setcount(uint32_t ticks); -static inline void xtensa_setcompare(uint32_t compare); static inline uint64_t up_tmr_total_count(void); static inline uint64_t up_tmr_getcount(void); static void IRAM_ATTR up_tmr_setcompare(uint32_t ticks); @@ -99,75 +97,18 @@ static int up_timer_expire(int irq, void *regs, FAR void *arg); * Private Data ****************************************************************************/ -static bool g_timer_started; -static uint64_t g_cticks; -static uint32_t g_loop_cnt; +static bool g_timer_started; /* Whether an interval timer is being started */ +static uint64_t g_cticks; /* Total ticks of system since power-on */ +static uint32_t g_loop_cnt; /* System Cycle counter cycle times */ + +/* Redundant ticks of an interval timer on the cycle counter */ + static uint32_t g_last_cticks; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Function: xtensa_getcount, xtensa_setcount - * xtensa_getcompare, and xtensa_setcompare - * - * Description: - * Lower level operations on Xtensa special registers. - * - ****************************************************************************/ - -/* Return the current value of the cycle count register */ - -static inline uint32_t xtensa_getcount(void) -{ - uint32_t count; - - __asm__ __volatile__ - ( - "rsr %0, CCOUNT" : "=r"(count) - ); - - return count; -} - -/* Set the value of the cycle count register */ - -static inline void xtensa_setcount(uint32_t ticks) -{ - __asm__ __volatile__ - ( - "wsr %0, ccount\n" - : - : "a"(ticks) - : "memory" - ); -} - -/* Return the old value of the compare register */ - -static inline uint32_t xtensa_getcompare(void) -{ - uint32_t compare; - - __asm__ __volatile__ - ( - "rsr %0, %1" : "=r"(compare) : "I"(XT_CCOMPARE) - ); - - return compare; -} - -/* Set the value of the compare register */ - -static inline void xtensa_setcompare(uint32_t compare) -{ - __asm__ __volatile__ - ( - "wsr %0, %1" : : "r"(compare), "I"(XT_CCOMPARE) - ); -} - /**************************************************************************** * Name: up_tmr_total_count * @@ -211,14 +152,14 @@ static inline uint64_t up_tmr_getcount(void) * Name: up_tmr_setcompare * * Description: - * Set the value of the compare register and - * save the currently running system tick. + * Set the value of the compare register, save the currently running + * system tick and clear cycle count register. * * Input Parameters: - * None + * ticks - Set the new value of the compare register * * Returned Value: - * Remaining ticks + * None * ****************************************************************************/ @@ -245,10 +186,11 @@ static void IRAM_ATTR up_tmr_setcompare(uint32_t ticks) static void IRAM_ATTR up_tmr_setcount(uint64_t ticks) { + irqstate_t flags; uint32_t loop_cnt; uint32_t last_ticks; - if (!ticks) + if (ticks == 0) { ticks = 1; } @@ -256,7 +198,7 @@ static void IRAM_ATTR up_tmr_setcount(uint64_t ticks) loop_cnt = ticks / CPU_TICKS_MAX; last_ticks = ticks % CPU_TICKS_MAX; - if (loop_cnt) + if (loop_cnt != 0) { xtensa_setcompare(CPU_TICKS_MAX); } @@ -265,10 +207,14 @@ static void IRAM_ATTR up_tmr_setcount(uint64_t ticks) xtensa_setcompare(last_ticks); } + flags = enter_critical_section(); + g_loop_cnt = loop_cnt; g_last_cticks = last_ticks; g_timer_started = true; + leave_critical_section(flags); + g_cticks += xtensa_getcount(); xtensa_setcount(0); } @@ -296,12 +242,12 @@ static int up_timer_expire(int irq, void *regs, FAR void *arg) if (g_timer_started) { - if (g_loop_cnt) + if (g_loop_cnt != 0) { --g_loop_cnt; - if (!g_loop_cnt) + if (g_loop_cnt == 0) { - if (g_last_cticks) + if (g_last_cticks != 0) { up_tmr_setcompare(g_last_cticks); } @@ -433,7 +379,7 @@ int IRAM_ATTR up_timer_cancel(FAR struct timespec *ts) flags = enter_critical_section(); - if (ts) + if (ts != NULL) { if (!g_timer_started) { @@ -503,7 +449,7 @@ int IRAM_ATTR up_timer_start(FAR const struct timespec *ts) } cpu_ticks = SEC_2_CTICK((uint64_t)ts->tv_sec) + - USEC_2_CTICK((uint64_t)ts->tv_nsec / 1000); + NSEC_2_CTICK((uint64_t)ts->tv_nsec); up_tmr_setcount(cpu_ticks); diff --git a/arch/xtensa/src/esp32/esp32_tickless.h b/arch/xtensa/src/esp32/esp32_tickless.h index c1fd420478e..156761a1d94 100644 --- a/arch/xtensa/src/esp32/esp32_tickless.h +++ b/arch/xtensa/src/esp32/esp32_tickless.h @@ -18,12 +18,14 @@ * ****************************************************************************/ +#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_TICKLESS_H +#define __ARCH_XTENSA_SRC_ESP32_ESP32_TICKLESS_H + /**************************************************************************** * Included Files ****************************************************************************/ -#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_TICKLESS_H -#define __ARCH_XTENSA_SRC_ESP32_ESP32_TICKLESS_H +#include /**************************************************************************** * Public Function Prototypes diff --git a/arch/xtensa/src/esp32/esp32_timerisr.c b/arch/xtensa/src/esp32/esp32_timerisr.c index cb7b928e352..01e3fee7379 100644 --- a/arch/xtensa/src/esp32/esp32_timerisr.c +++ b/arch/xtensa/src/esp32/esp32_timerisr.c @@ -33,7 +33,7 @@ #include #include "clock/clock.h" -#include "xtensa_timer.h" +#include "xtensa_counter.h" #include "xtensa.h" /**************************************************************************** @@ -46,52 +46,6 @@ static uint32_t g_tick_divisor; * Private Functions ****************************************************************************/ -/**************************************************************************** - * Function: xtensa_getcount, xtensa_getcompare, and xtensa_setcompare - * - * Description: - * Lower level operations on Xtensa special registers. - * - ****************************************************************************/ - -/* Return the current value of the cycle count register */ - -static inline uint32_t xtensa_getcount(void) -{ - uint32_t count; - - __asm__ __volatile__ - ( - "rsr %0, CCOUNT" : "=r"(count) - ); - - return count; -} - -/* Return the old value of the compare register */ - -static inline uint32_t xtensa_getcompare(void) -{ - uint32_t compare; - - __asm__ __volatile__ - ( - "rsr %0, %1" : "=r"(compare) : "I"(XT_CCOMPARE) - ); - - return compare; -} - -/* Set the value of the compare register */ - -static inline void xtensa_setcompare(uint32_t compare) -{ - __asm__ __volatile__ - ( - "wsr %0, %1" : : "r"(compare), "I"(XT_CCOMPARE) - ); -} - /**************************************************************************** * Function: esp32_timerisr * diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/autopm/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/autopm/defconfig index f672c34c9a4..a03c1ffb5a3 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/autopm/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/autopm/defconfig @@ -63,7 +63,6 @@ CONFIG_SCHED_LPWORK=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y CONFIG_SIG_DEFAULT=y -CONFIG_SPI=y CONFIG_SPIFFS_NAME_MAX=48 CONFIG_START_DAY=6 CONFIG_START_MONTH=12 diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/tickless/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/tickless/defconfig index 1a81d405e75..66d62bbf45a 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/tickless/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/tickless/defconfig @@ -39,7 +39,6 @@ CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y -CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 CONFIG_START_YEAR=2011 diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c index 2251400b516..33695bcdde4 100644 --- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c @@ -194,8 +194,7 @@ int esp32_bringup(void) ret = esp32_rt_timer_init(); if (ret < 0) { - syslog(LOG_ERR, "Failed to initialize RT timer error\n"); - return ret; + syslog(LOG_ERR, "Failed to initialize RT timer: %d\n", ret); } #endif diff --git a/boards/xtensa/esp32/esp32-ethernet-kit/configs/autopm/defconfig b/boards/xtensa/esp32/esp32-ethernet-kit/configs/autopm/defconfig index 95e2a3ec197..b996c8933e7 100644 --- a/boards/xtensa/esp32/esp32-ethernet-kit/configs/autopm/defconfig +++ b/boards/xtensa/esp32/esp32-ethernet-kit/configs/autopm/defconfig @@ -62,7 +62,6 @@ CONFIG_SCHED_LPWORK=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y CONFIG_SIG_DEFAULT=y -CONFIG_SPI=y CONFIG_SPIFFS_NAME_MAX=48 CONFIG_START_DAY=6 CONFIG_START_MONTH=12 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 1c4451209e8..20b33092a71 100644 --- a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c @@ -161,8 +161,7 @@ int esp32_bringup(void) ret = esp32_rt_timer_init(); if (ret < 0) { - syslog(LOG_ERR, "Failed to initialize RT timer error\n"); - return ret; + syslog(LOG_ERR, "Failed to initialize RT timer: %d\n", ret); } #endif diff --git a/boards/xtensa/esp32/esp32-wrover-kit/configs/autopm/defconfig b/boards/xtensa/esp32/esp32-wrover-kit/configs/autopm/defconfig index f5916f30383..800fbf9dfc9 100644 --- a/boards/xtensa/esp32/esp32-wrover-kit/configs/autopm/defconfig +++ b/boards/xtensa/esp32/esp32-wrover-kit/configs/autopm/defconfig @@ -63,7 +63,6 @@ CONFIG_SCHED_LPWORK=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y CONFIG_SIG_DEFAULT=y -CONFIG_SPI=y CONFIG_SPIFFS_NAME_MAX=48 CONFIG_START_DAY=6 CONFIG_START_MONTH=12 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 cae5ac7b8ff..5012d2e751c 100644 --- a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c @@ -181,8 +181,7 @@ int esp32_bringup(void) ret = esp32_rt_timer_init(); if (ret < 0) { - syslog(LOG_ERR, "Failed to initialize RT timer error\n"); - return ret; + syslog(LOG_ERR, "Failed to initialize RT timer: %d\n", ret); } #endif