esp32[c3]: Add RTC IRQ support

This commit is contained in:
Eren Terzioglu 2024-05-13 10:26:31 +03:00 committed by Xiang Xiao
parent 07f0e0c166
commit 44e118eaf2
5 changed files with 391 additions and 2 deletions

View file

@ -302,6 +302,13 @@ config ESPRESSIF_GPIO_IRQ
---help---
Enable support for interrupting GPIO pins
config ESPRESSIF_RTCIO_IRQ
bool "RTC IO interrupts"
default n
depends on !ARCH_CHIP_ESP32H2 && !ARCH_CHIP_ESP32C6
---help---
Enable support for RTC peripherals interrupts.
config ESPRESSIF_LEDC
bool "LEDC (PWM)"
default n

View file

@ -31,7 +31,7 @@ CHIP_ASRCS = esp_vectors.S
# Required Espressif chip's files (arch/risc-v/src/common/espressif)
CHIP_CSRCS = esp_allocateheap.c esp_start.c esp_idle.c
CHIP_CSRCS += esp_irq.c esp_gpio.c esp_libc_stubs.c
CHIP_CSRCS += esp_irq.c esp_gpio.c esp_rtc_gpio.c esp_libc_stubs.c
CHIP_CSRCS += esp_lowputc.c esp_serial.c
CHIP_CSRCS += esp_systemreset.c
@ -107,7 +107,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = 581540ed0a5ce9674da44f9ece6a63d052058985
ESP_HAL_3RDPARTY_VERSION = ee8c7b0ad6a117465312d4c9a6e654cb7b2b9469
endif
ifndef ESP_HAL_3RDPARTY_URL

View file

@ -37,6 +37,7 @@
#include "esp_gpio.h"
#include "esp_irq.h"
#include "esp_rtc_gpio.h"
#include "esp_attr.h"
#include "esp_bit_defs.h"
@ -320,6 +321,10 @@ void up_irqinitialize(void)
esp_gpioirqinitialize();
#endif
/* Initialize RTCIO interrupt support */
esp_rtcioirqinitialize();
/* Attach the common interrupt handler */
riscv_exception_attach();

View file

@ -0,0 +1,264 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_rtc_gpio.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 <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include "irq.h"
#include "riscv_internal.h"
#include "esp_irq.h"
#include "esp_rtc_gpio.h"
#include "soc/rtc_io_periph.h"
#include "hal/rtc_io_hal.h"
#include "soc/rtc_cntl_periph.h"
#include "soc/periph_defs.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_ARCH_CHIP_ESP32C3_GENERIC
#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ
static int g_rtcio_cpuint;
static uint32_t last_status;
#ifdef CONFIG_ARCH_CHIP_ESP32C3_GENERIC
static const int rtc_irq_reg_shift[ESP_NIRQ_RTCIO] =
{
RTC_CNTL_SLP_WAKEUP_INT_ENA_S,
RTC_CNTL_SLP_REJECT_INT_ENA_S,
RTC_CNTL_WDT_INT_ENA_S,
RTC_CNTL_BROWN_OUT_INT_ENA_S,
RTC_CNTL_MAIN_TIMER_INT_ENA_S,
RTC_CNTL_SWD_INT_ENA_S,
RTC_CNTL_XTAL32K_DEAD_INT_ENA_S,
RTC_CNTL_GLITCH_DET_INT_ENA_S,
RTC_CNTL_BBPLL_CAL_INT_ENA_S
};
#define RTC_IRQ_REG_SHIFT(x) rtc_irq_reg_shift[x]
#endif /* CONFIG_ARCH_CHIP_ESP32C3 */
#endif /* CONFIG_ESPRESSIF_RTCIO_IRQ */
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: rtcio_dispatch
*
* Description:
* Second level dispatch for the RTC interrupt.
*
* Input Parameters:
* irq - The IRQ number;
* reg_status - Pointer to a copy of the interrupt status register.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ
static void rtcio_dispatch(int irq, uint32_t *reg_status)
{
uint32_t status = *reg_status;
uint32_t mask;
int i;
/* Check each bit in the status register */
for (i = 0; i < ESP_NIRQ_RTCIO && status != 0; i++)
{
/* Check if there is an interrupt pending for this type */
mask = (UINT32_C(1) << RTC_IRQ_REG_SHIFT(i));
if ((status & mask) != 0)
{
/* Yes... perform the second level dispatch. The IRQ context will
* contain the contents of the status register.
*/
irq_dispatch(irq + i, (void *)reg_status);
/* Clear the bit in the status so that we might execute this loop
* sooner.
*/
status &= ~mask;
}
}
}
/****************************************************************************
* Name: rtcio_interrupt
*
* Description:
* RTC interrupt handler.
*
* Input Parameters:
* irq - The IRQ number;
* context - The interrupt context;
* args - The arguments passed to the handler.
*
* Returned Value:
* Zero (OK).
*
****************************************************************************/
static int rtcio_interrupt(int irq, void *context, void *arg)
{
/* Read and clear the lower RTC interrupt status */
last_status = getreg32(RTC_CNTL_INT_ST_REG);
putreg32(last_status, RTC_CNTL_INT_CLR_REG);
/* Dispatch pending interrupts in the RTC status register */
rtcio_dispatch(ESP_FIRST_RTCIOIRQ, &last_status);
return OK;
}
#endif /* CONFIG_ESPRESSIF_RTCIO_IRQ */
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp_rtcioirqinitialize
*
* Description:
* Initialize logic to support a second level of interrupt decoding for
* RTC IRQs.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ
void esp_rtcioirqinitialize(void)
{
/* Setup the RTCIO interrupt. */
g_rtcio_cpuint = esp_setup_irq(ETS_RTC_CORE_INTR_SOURCE,
1, ESP_IRQ_TRIGGER_LEVEL);
DEBUGASSERT(g_rtcio_cpuint >= 0);
/* Attach and enable the interrupt handler */
DEBUGVERIFY(irq_attach(ESP_IRQ_RTC_CORE, rtcio_interrupt, NULL));
up_enable_irq(ESP_IRQ_RTC_CORE);
}
/****************************************************************************
* Name: esp_rtcioirqenable
*
* Description:
* Enable the interrupt for the specified RTC peripheral IRQ.
*
* Input Parameters:
* irq - The IRQ number.
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_rtcioirqenable(int irq)
{
uintptr_t regaddr = RTC_CNTL_INT_ENA_REG;
uint32_t regval;
int bit;
DEBUGASSERT(irq >= ESP_FIRST_RTCIOIRQ &&
irq <= ESP_LAST_RTCIOIRQ);
/* Convert the IRQ number to the corresponding bit */
bit = RTC_IRQ_REG_SHIFT(irq - ESP_FIRST_RTCIOIRQ);
/* Get the address of the GPIO PIN register for this pin */
up_disable_irq(ESP_IRQ_RTC_CORE);
regval = getreg32(regaddr) | (UINT32_C(1) << bit);
putreg32(regval, regaddr);
up_enable_irq(ESP_IRQ_RTC_CORE);
}
/****************************************************************************
* Name: esp_rtcioirqdisable
*
* Description:
* Disable the interrupt for the specified RTC peripheral IRQ.
*
* Input Parameters:
* irq - The IRQ number.
*
* Returned Value:
* None.
*
****************************************************************************/
void esp_rtcioirqdisable(int irq)
{
uintptr_t regaddr = RTC_CNTL_INT_ENA_REG;
uint32_t regval;
int bit;
DEBUGASSERT(irq >= ESP_FIRST_RTCIOIRQ &&
irq <= ESP_LAST_RTCIOIRQ);
/* Convert the IRQ number to the corresponding bit */
bit = RTC_IRQ_REG_SHIFT(irq - ESP_FIRST_RTCIOIRQ);
/* Disable IRQ */
up_disable_irq(ESP_IRQ_RTC_CORE);
regval = getreg32(regaddr) & (~(UINT32_C(1) << bit));
putreg32(regval, regaddr);
up_enable_irq(ESP_IRQ_RTC_CORE);
}
#endif /* CONFIG_ESPRESSIF_RTCIO_IRQ */
#endif /* CONFIG_ARCH_CHIP_ESP32C3_GENERIC */

View file

@ -0,0 +1,113 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_rtc_gpio.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_RISC_V_SRC_COMMON_ESPRESSIF_ESP_RTC_GPIO_H
#define __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_RTC_GPIO_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_rtcioirqinitialize
*
* Description:
* Initialize logic to support a second level of interrupt decoding for
* RTC IRQs.
*
* Input Parameters:
* None.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ
void esp_rtcioirqinitialize(void);
#else
# define esp_rtcioirqinitialize()
#endif
/****************************************************************************
* Name: esp_rtcioirqenable
*
* Description:
* Enable the interrupt for the specified RTC peripheral IRQ.
*
* Input Parameters:
* irq - The IRQ number.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ
void esp_rtcioirqenable(int irq);
#else
# define esp_rtcioirqenable(irq)
#endif
/****************************************************************************
* Name: esp_rtcioirqdisable
*
* Description:
* Disable the interrupt for the specified RTC peripheral IRQ.
*
* Input Parameters:
* irq - The IRQ number.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ
void esp_rtcioirqdisable(int irq);
#else
# define esp_rtcioirqdisable(irq)
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_RTC_GPIO_H */