mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #13061 from gschorcht/cpu/esp32/rtc_xtal_32k
cpu/esp32: allow external 32 kHz crystal for the RTC hardware timer
This commit is contained in:
commit
66c7c63c94
@ -10,5 +10,6 @@ FEATURES_PROVIDED += periph_spi
|
||||
# unique features provided by the board
|
||||
FEATURES_PROVIDED += sdcard_spi
|
||||
FEATURES_PROVIDED += esp_spi_ram
|
||||
FEATURES_PROVIDED += esp_rtc_timer_32k
|
||||
|
||||
FEATURES_PROVIDED += arduino
|
||||
|
@ -33,6 +33,7 @@ The Espressif ESP-WROVER-KIT is a development board that uses the ESP32-WROVER m
|
||||
- 3.2" SPI LCD panel
|
||||
- RGB LED
|
||||
- USB bridge with JTAG interface
|
||||
- external 32.768 kHz crystal for RTC
|
||||
|
||||
Furthermore, many GPIOs are broken out for extension. The USB bridge based on FDI FT2232HL provides a JTAG interface for OCD debugging through the USB interface.
|
||||
|
||||
@ -90,6 +91,7 @@ ESP-WROVER-KIT has the following on-board components
|
||||
- 3.2" SPI LCD panel
|
||||
- RGB LED
|
||||
- USB bridge with JTAG interface
|
||||
- external 32.768 kHz crystal for RTC
|
||||
|
||||
The following table shows the default board configuration sorted according to the defined functionality of GPIOs for different hardware options. This configuration can be overridden by \ref esp32_app_spec_conf "application-specific configurations".
|
||||
|
||||
@ -192,7 +194,7 @@ GPIO39 | ADC_LINE(3) | ADC_LINE(3) | ADC_LINE(3) | CA
|
||||
- GPIO2 cannot be used as PWM_DEV(0) channel 1 / LED0 when SPI_DEV(0) is used in any way. Reason is that GPIO2 is the MISO signal when SPI_DEV(0) is used and is therefore an input. PWM channels are outputs.
|
||||
- It might be necessary to remove the SD card or the peripheral hardware attached to the SPI_DEV(0) interface for flashing RIOT. Reason is that the **SPI_DEV(0)** interface uses the HSPI interface with the GPIO2 pin as the MISO signal, which has bootstrapping functionality.
|
||||
- GPIO16 and GPIO17 are used for the built-in SPI RAM and are not available on the I/O expansion connector, even though they are labeled there.
|
||||
- GPIO32 and GPIO33 are attached to a 32 kHz crystal by default. GPIO32 and GPIO33 are standard connected to a 32 kHz crystal. To make them available as a GPIO on the I/O expansion connector, SMD resistors would need to be removed and soldered.
|
||||
- GPIO32 and GPIO33 are attached to a 32 kHz crystal by default. To make them available as a GPIO on the I/O expansion connector, SMD resistors would need to be removed and soldered. Module `esp_rtc_timer_32k` is enabled by default.
|
||||
|
||||
For detailed information about the configuration of ESP32 boards, see
|
||||
section Peripherals in \ref esp32_riot.
|
||||
|
@ -43,6 +43,18 @@ ifneq (,$(filter esp_idf_nvs_flash,$(USEMODULE)))
|
||||
USEMODULE += pthread
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_rtc,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += esp_rtc_timer_32k
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_rtc_timer_32k,$(FEATURES_USED)))
|
||||
USEMODULE += esp_rtc_timer_32k
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_rtc_timer_32k,$(USEMODULE)))
|
||||
USEMODULE += esp_rtc_timer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_i2c,$(USEMODULE)))
|
||||
ifneq (,$(filter esp_i2c_hw,$(USEMODULE)))
|
||||
USEMODULE += core_thread_flags
|
||||
|
@ -93,6 +93,7 @@ PSEUDOMODULES += esp_log_colored
|
||||
PSEUDOMODULES += esp_log_tagged
|
||||
PSEUDOMODULES += esp_log_startup
|
||||
PSEUDOMODULES += esp_rtc_timer
|
||||
PSEUDOMODULES += esp_rtc_timer_32k
|
||||
PSEUDOMODULES += esp_spi_ram
|
||||
PSEUDOMODULES += esp_spiffs
|
||||
PSEUDOMODULES += esp_wifi_any
|
||||
@ -110,7 +111,6 @@ USEMODULE += periph
|
||||
USEMODULE += periph_adc_ctrl
|
||||
USEMODULE += periph_hwrng
|
||||
USEMODULE += periph_flash
|
||||
USEMODULE += periph_rtc
|
||||
USEMODULE += periph_uart
|
||||
USEMODULE += riot_freertos
|
||||
USEMODULE += random
|
||||
|
@ -38,9 +38,10 @@
|
||||
5. [PWM Channels](#esp32_pwm_channels)
|
||||
6. [SPI Interfaces](#esp32_spi_interfaces)
|
||||
7. [Timers](#esp32_timers)
|
||||
8. [UART Interfaces](#esp32_uart_interfaces)
|
||||
9. [CAN Interfaces](#esp32_can_interfaces)
|
||||
10. [Other Peripherals](#esp32_other_peripherals)
|
||||
8. [RTC Timer](#esp32_rtc_timer)
|
||||
9. [UART Interfaces](#esp32_uart_interfaces)
|
||||
10. [CAN Interfaces](#esp32_can_interfaces)
|
||||
11. [Other Peripherals](#esp32_other_peripherals)
|
||||
7. [Special On-board Peripherals](#esp32_special_on_board_peripherals)
|
||||
1. [SPI RAM Modules](#esp32_spi_ram)
|
||||
2. [SPIFFS Device](#esp32_spiffs_device)
|
||||
@ -118,6 +119,8 @@ Module | Default | Short description
|
||||
[esp_log_startup](#esp32_esp_log_module) | not used | enable additional startup information
|
||||
[esp_log_tagged](#esp32_esp_log_module) | not used | add additional information to the log output
|
||||
[esp_now](#esp32_esp_now_network_interface) | not used | enable the ESP-NOW network device
|
||||
[esp_rtc_timer](#esp32_rtc_timer) | not used | enable RTC hardware timer with internal 150 kHz RC oscillator
|
||||
[esp_rtc_timer_32k](#esp32_rtc_timer) not used | enable RTC hardware timer with external 32.768 kHz crystal.
|
||||
[esp_spi_ram](#esp32_spi_ram) | not used | enable SPI RAM
|
||||
[esp_spiffs](#esp32_spiffs_device) | not used | enable SPIFFS for on-board flash memory
|
||||
[esp_wifi](#esp32_wifi_network_interface) | not used | enable the Wifi network device
|
||||
@ -416,6 +419,8 @@ esp_log_colored | Enable colored log output, see section [Log output](#esp32_esp
|
||||
esp_log_startup | Enable additional startup information, see section [Log output](#esp32_esp_log_module).
|
||||
esp_log_tagged | Add additional information to the log output, see section [Log output](#esp32_esp_log_module).
|
||||
esp_now | Enable the built-in WiFi module with the ESP-NOW protocol as `netdev` network device, see section [ESP-NOW Network Interface](#esp32_esp_now_network_interface).
|
||||
esp_rtc_timer | Enable RTC hardware timer with internal 150 kHz RC oscillator.
|
||||
esp_rtc_timer_32k | Enable RTC hardware timer with external 32.768 kHz crystal.
|
||||
esp_spiffs | Enable the optional SPIFFS drive in on-board flash memory, see section [SPIFFS Device](#esp32_spiffs_device).
|
||||
esp_spi_ram | Enable the optional SPI RAM, see section [SPI RAM Modules](#esp32_spi_ram).
|
||||
esp_wifi | Enable the built-in WiFi module as `netdev` network device, see section [WiFi Network Interface](#esp32_wifi_network_interface).
|
||||
@ -826,6 +831,38 @@ to application's makefile.
|
||||
|
||||
Timers are MCU built-in features and not board-specific. There is nothing to be configured.
|
||||
|
||||
\anchor esp32_rtc_timer
|
||||
## <a name="esp32_rtc_timer"> RTC Timer </a> [[TOC](#esp32_toc)]
|
||||
|
||||
The RTC hardware timer of the ESP32 can be clocked with either an external
|
||||
32.768 kHz crystal or the internal adjustable 150 kHz RC oscillator. If the
|
||||
the external 32.768 kHz crystal is not available, the internal 150 kHz RC
|
||||
oscillator is used automatically. However, since this internal 150 kHz RC
|
||||
oscillator is not very accurate, the RTC low-level driver uses by default
|
||||
the PLL-controlled 64-bit microsecond system timer to emulate the RTC timer.
|
||||
|
||||
To allow the use of the RTC hardware timer for boards with an external
|
||||
32 kHz crystal, the pseudomodules `esp_rtc_timer` and `esp_rtc_timer_32k`
|
||||
can be used to control which timer is used by the RTC low-level driver
|
||||
as following:
|
||||
|
||||
- **esp_rtc_timer**:
|
||||
Use always the RTC hardware timer with the **internal 150 kHz RC** oscillator.
|
||||
|
||||
- **esp_rtc_timer_32k**:
|
||||
Use the RTC hardware timer with the **external 32.768 kHz crystal**. If the
|
||||
external 32.768 kHz crystal is not available, the RTC hardware timer
|
||||
is used with the internal 150 kHz RC oscillator.
|
||||
|
||||
If none of the modules above is enabled, the PLL-driven **emulated RTC timer**
|
||||
is used. In this case, the RTC hardware timer with the internal RC 150 kHz
|
||||
oscillator is only used in deep sleep mode and during a reset.
|
||||
|
||||
@note The accuracy of the emulated RTC timer is better than the accuracy of the
|
||||
RTC hardware timer with the internal 150 kHz RC oscillator. If you have not
|
||||
connected an external 32.768 kHz crystal, you should use the default
|
||||
configuration.
|
||||
|
||||
\anchor esp32_uart_interfaces
|
||||
## <a name="esp32_uart_interfaces"> UART Interfaces </a> [[TOC](#esp32_toc)]
|
||||
|
||||
@ -920,7 +957,6 @@ when needed.
|
||||
The ESP32 port of RIOT also supports:
|
||||
|
||||
- hardware number generator with 32 bit
|
||||
- RTC device
|
||||
- CPU-ID function
|
||||
- Vref measurement function
|
||||
- power management functions
|
||||
|
@ -218,8 +218,13 @@ gpio_pin_usage_t _gpio_pin_usage [GPIO_PIN_NUMOF] = {
|
||||
_NOT_EXIST, /* gpio29 */
|
||||
_NOT_EXIST, /* gpio30 */
|
||||
_NOT_EXIST, /* gpio31 */
|
||||
#if MODULE_ESP_RTC_TIMER_32K
|
||||
_NOT_EXIST, /* gpio32 used for external 32K crystal */
|
||||
_NOT_EXIST, /* gpio33 used for external 32K crystal */
|
||||
#else
|
||||
_GPIO, /* gpio32 */
|
||||
_GPIO, /* gpio33 */
|
||||
#endif
|
||||
_GPIO, /* gpio34 */
|
||||
_GPIO, /* gpio35 */
|
||||
_GPIO, /* gpio36 */
|
||||
|
@ -20,11 +20,28 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* If module esp_rtc_timer is enabled, the 48-bit RTC hardware timer is used
|
||||
* directly. Otherwise the PLL driven 64-bit microsecond system timer is used
|
||||
* to emulate a RTC timer (default). This emulated RTC timer results into much
|
||||
* better accuracy. The Advantage of using RTC hardware timer over system timer
|
||||
* is that it would also continue in deep sleep mode and after software reset.
|
||||
* The RTC low-level driver uses either the RTC hardware timer directly or the
|
||||
* PLL-controlled 64-bit microsecond system timer to emulate an RTC timer. The
|
||||
* RTC hardware timer can be clocked with either an external 32.768 kHz crystal
|
||||
* or an internal adjustable 150 kHz RC oscillator. Which RTC timer is used,
|
||||
* is controlled by modules as following:
|
||||
*
|
||||
* default
|
||||
* Since the RTC hardware timer with the 150 kHz RC oscillator is less
|
||||
* accurate than the emulated RTC timer, the emulated RTC timer is used by
|
||||
* default. In this case, the RTC hardware timer is only used with the
|
||||
* internal 150 kHz oscillator in deep sleep mode and during a reset.
|
||||
*
|
||||
* module `esp_rtc_timer`
|
||||
* To use the RTC hardware timer with the 150 kHz Oscilator, the module
|
||||
* `esp_rtc_timer` has to be enabled.
|
||||
*
|
||||
* module `esp_rtc_timer_32k`
|
||||
* To use the RTC hardware timer with the external 32.768 kHz crystal, the
|
||||
* module 'esp_rtc_timer_32k` has to be enabled. If the module
|
||||
* `esp_rtc_timer_32k` is used, but no external 32.768 kHz crystal is
|
||||
* available, the RTC low-level driver uses the RTC hardware driver,
|
||||
* but with the internal 150 kHz RC oscillator.
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
@ -51,6 +68,9 @@
|
||||
#define TIMER_SYSTEM_INT_MASK BIT(0)
|
||||
#define TIMER_SYSTEM_INT_SRC ETS_TG0_T0_LEVEL_INTR_SOURCE
|
||||
|
||||
/* RTC timer interrupt source */
|
||||
#define TIMER_RTC_INT_SRC ETS_RTC_CORE_INTR_SOURCE
|
||||
|
||||
#define RTC_CLK_CAL_FRACT 19 /* fractional bits of calibration value */
|
||||
|
||||
/* we can't include soc/rtc.h because of rtc_init declaration conflicts */
|
||||
@ -64,7 +84,7 @@ static time_t _sys_alarm_time = 0;
|
||||
|
||||
#define RTC_BSS_ATTR __attribute__((section(".rtc.bss")))
|
||||
|
||||
/* save several time stamps */
|
||||
/* save several time stamps in RTC memory */
|
||||
static uint64_t RTC_BSS_ATTR _rtc_time_init_us; /* RTC time on init in us */
|
||||
static uint64_t RTC_BSS_ATTR _rtc_time_init; /* RTC time on init in cycles */
|
||||
static uint64_t RTC_BSS_ATTR _rtc_time_set_us; /* RTC time on set in us */
|
||||
@ -164,19 +184,12 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg)
|
||||
_sys_alarm_time = mktime(time);
|
||||
time_t _sys_time_offset = _sys_alarm_time - _sys_time_set;
|
||||
|
||||
/*
|
||||
* RTC doesn't provide alarm functionality in active mode. At least
|
||||
* the RTC main timer seems not to work. Therefore we always use the
|
||||
* system timer for alarms. The Advantage of using RTC over system timer
|
||||
* is that it also continues in deep sleep and after software reset.
|
||||
*/
|
||||
#if 0 /* TODO should be MODULE_ESP_RTC_TIMER */
|
||||
#if MODULE_ESP_RTC_TIMER
|
||||
|
||||
/* determine the offset of alarm time to current time in RTC time */
|
||||
uint64_t _rtc_time_alarm;
|
||||
_rtc_time_alarm = _rtc_time_set + _sys_time_offset * rtc_clk_slow_freq_get_hz();
|
||||
|
||||
DEBUG("%s sys=%d sys_alarm=%d rtc=%lld rtc_alarm=%lld\n", __func__,
|
||||
DEBUG("%s sys=%ld sys_alarm=%ld rtc=%lld rtc_alarm=%lld\n", __func__,
|
||||
_sys_get_time(), _sys_time_offset, _rtc_get_time_raw(), _rtc_time_alarm);
|
||||
|
||||
/* set the timer value */
|
||||
@ -193,7 +206,7 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg)
|
||||
RTCCNTL.int_ena.rtc_main_timer = 1;
|
||||
|
||||
/* route all RTC interrupt sources to the same level type interrupt */
|
||||
intr_matrix_set(PRO_CPU_NUM, DPORT_PRO_RTC_CORE_INTR_MAP_REG, CPU_INUM_RTC);
|
||||
intr_matrix_set(PRO_CPU_NUM, ETS_RTC_CORE_INTR_SOURCE, CPU_INUM_RTC);
|
||||
|
||||
/* set interrupt handler and enable the CPU interrupt */
|
||||
xt_set_interrupt_handler(CPU_INUM_RTC, _rtc_timer_handler, NULL);
|
||||
@ -238,7 +251,7 @@ void rtc_clear_alarm(void)
|
||||
_rtc_alarm_cb = NULL;
|
||||
_rtc_alarm_arg = NULL;
|
||||
|
||||
#if 0 /* TODO should be MODULE_ESP_RTC_TIMER, see rtc_set_alarm */
|
||||
#if MODULE_ESP_RTC_TIMER
|
||||
|
||||
/* disable RTC timer alarm and disable the RTC timer interrupt */
|
||||
RTCCNTL.slp_timer1.main_timer_alarm_en = 0;
|
||||
@ -301,10 +314,12 @@ static void IRAM_ATTR _rtc_timer_handler(void* arg)
|
||||
{
|
||||
irq_isr_enter();
|
||||
|
||||
#if 0 /* TODO should be MODULE_ESP_RTC_TIMER */
|
||||
#if MODULE_ESP_RTC_TIMER
|
||||
|
||||
/* check for RTC timer interrupt */
|
||||
/* check for RTC timer interrupt */
|
||||
if (RTCCNTL.int_st.rtc_main_timer) {
|
||||
/* disable RTC timer alarm */
|
||||
RTCCNTL.slp_timer1.main_timer_alarm_en = 0;
|
||||
/* clear the interrupt */
|
||||
RTCCNTL.int_clr.rtc_main_timer = 1;
|
||||
/* call back registered function */
|
||||
|
@ -215,8 +215,13 @@ static void IRAM system_clk_init (void)
|
||||
/* set FAST_CLK to internal low power clock of 8 MHz */
|
||||
rtc_clk_fast_freq_set(RTC_FAST_FREQ_8M);
|
||||
|
||||
#if MODULE_ESP_RTC_TIMER_32K
|
||||
/* set SLOW_CLK to external 32.768 kHz crystal clock */
|
||||
rtc_select_slow_clk(RTC_SLOW_FREQ_32K_XTAL);
|
||||
#else
|
||||
/* set SLOW_CLK to internal low power clock of 150 kHz */
|
||||
rtc_select_slow_clk(RTC_SLOW_FREQ_RTC);
|
||||
#endif
|
||||
|
||||
LOG_STARTUP("Switching system clocks can lead to some unreadable characters\n");
|
||||
|
||||
@ -326,11 +331,13 @@ static NORETURN void IRAM system_init (void)
|
||||
periph_init();
|
||||
|
||||
/* print system time */
|
||||
#ifdef MODULE_PERIPH_RTC
|
||||
struct tm _sys_time;
|
||||
rtc_get_time(&_sys_time);
|
||||
LOG_STARTUP("System time: %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
_sys_time.tm_year + 1900, _sys_time.tm_mon + 1, _sys_time.tm_mday,
|
||||
_sys_time.tm_hour, _sys_time.tm_min, _sys_time.tm_sec);
|
||||
#endif
|
||||
|
||||
/* print the board config */
|
||||
#ifdef MODULE_ESP_LOG_STARTUP
|
||||
|
Loading…
Reference in New Issue
Block a user