interrupt_controller: intc_esp32c3: added intc driver
For esp32c3 and replaces the hardcoded interrupt attaching procedures with this new driver. Signed-off-by: Felipe Neves <felipe.neves@espressif.com>
This commit is contained in:
parent
a8f02ed5ee
commit
b97c2da2f2
12 changed files with 381 additions and 37 deletions
|
@ -23,5 +23,6 @@ zephyr_library_sources_ifdef(CONFIG_RV32M1_INTMUX intc_rv32m1_intmux.c
|
||||||
zephyr_library_sources_ifdef(CONFIG_SAM0_EIC intc_sam0_eic.c)
|
zephyr_library_sources_ifdef(CONFIG_SAM0_EIC intc_sam0_eic.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_SHARED_IRQ intc_shared_irq.c)
|
zephyr_library_sources_ifdef(CONFIG_SHARED_IRQ intc_shared_irq.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c)
|
zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_INTC_ESP32C3 intc_esp32c3.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
|
zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
|
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
|
||||||
|
|
|
@ -69,6 +69,8 @@ source "drivers/interrupt_controller/Kconfig.intel_vtd"
|
||||||
|
|
||||||
source "drivers/interrupt_controller/Kconfig.esp32"
|
source "drivers/interrupt_controller/Kconfig.esp32"
|
||||||
|
|
||||||
|
source "drivers/interrupt_controller/Kconfig.esp32c3"
|
||||||
|
|
||||||
source "drivers/interrupt_controller/Kconfig.xec"
|
source "drivers/interrupt_controller/Kconfig.xec"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
10
drivers/interrupt_controller/Kconfig.esp32c3
Normal file
10
drivers/interrupt_controller/Kconfig.esp32c3
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config INTC_ESP32C3
|
||||||
|
bool "Enables ESP32C3 interrupt controller driver"
|
||||||
|
depends on SOC_ESP32C3
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enables the esp32c3 interrupt controller driver to handle ISR
|
||||||
|
management at SoC level.
|
193
drivers/interrupt_controller/intc_esp32c3.c
Normal file
193
drivers/interrupt_controller/intc_esp32c3.c
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <soc/periph_defs.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include <soc.h>
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <drivers/interrupt_controller/intc_esp32c3.h>
|
||||||
|
#include <sw_isr_table.h>
|
||||||
|
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(intc_esp32c3, CONFIG_LOG_DEFAULT_LEVEL);
|
||||||
|
|
||||||
|
#define ESP32C3_INTC_DEFAULT_PRIORITY 15
|
||||||
|
#define ESP32C3_INTC_DEFAULT_THRESHOLD 1
|
||||||
|
#define ESP32C3_INTC_DISABLED_SLOT 31
|
||||||
|
#define ESP32C3_INTC_SRCS_PER_IRQ 2
|
||||||
|
#define ESP32C3_INTC_AVAILABLE_IRQS 30
|
||||||
|
|
||||||
|
static uint32_t esp_intr_enabled_mask[2] = {0, 0};
|
||||||
|
|
||||||
|
static void esp_intr_default_isr(const void *arg)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(arg);
|
||||||
|
ulong_t mcause;
|
||||||
|
|
||||||
|
__asm__ volatile("csrr %0, mcause" : "=r" (mcause));
|
||||||
|
mcause &= SOC_MCAUSE_EXP_MASK;
|
||||||
|
|
||||||
|
LOG_DBG("Spurious interrupt, mcause: %ld, source %d", mcause, soc_intr_get_next_source());
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t esp_intr_find_irq_for_source(uint32_t source)
|
||||||
|
{
|
||||||
|
/* in general case, each 2 sources goes routed to
|
||||||
|
* 1 IRQ line.
|
||||||
|
*/
|
||||||
|
uint32_t irq = (source / ESP32C3_INTC_SRCS_PER_IRQ);
|
||||||
|
|
||||||
|
if (irq > ESP32C3_INTC_AVAILABLE_IRQS) {
|
||||||
|
LOG_DBG("Clamping the source: %d no more IRQs available", source);
|
||||||
|
irq = ESP32C3_INTC_AVAILABLE_IRQS;
|
||||||
|
} else if (irq == 0) {
|
||||||
|
irq = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Found IRQ: %d for source: %d", irq, source);
|
||||||
|
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_intr_initialize(void)
|
||||||
|
{
|
||||||
|
/* IRQ 31 is reserved for disabled interrupts,
|
||||||
|
* so route all sources to it
|
||||||
|
*/
|
||||||
|
for (int i = 0 ; i < ESP32C3_INTC_AVAILABLE_IRQS + 2; i++) {
|
||||||
|
irq_disable(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
|
||||||
|
esp_rom_intr_matrix_set(0,
|
||||||
|
i,
|
||||||
|
ESP32C3_INTC_DISABLED_SLOT);
|
||||||
|
|
||||||
|
irq_connect_dynamic(i,
|
||||||
|
ESP32C3_INTC_DEFAULT_PRIORITY,
|
||||||
|
esp_intr_default_isr,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set global esp32c3's INTC masking level */
|
||||||
|
esprv_intc_int_set_threshold(ESP32C3_INTC_DEFAULT_THRESHOLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp_intr_alloc(int source,
|
||||||
|
int flags,
|
||||||
|
isr_handler_t handler,
|
||||||
|
void *arg,
|
||||||
|
void **ret_handle)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(flags);
|
||||||
|
ARG_UNUSED(ret_handle);
|
||||||
|
|
||||||
|
if (handler == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t key = irq_lock();
|
||||||
|
uint32_t irq = esp_intr_find_irq_for_source(source);
|
||||||
|
|
||||||
|
esp_rom_intr_matrix_set(0, source, irq);
|
||||||
|
|
||||||
|
irq_connect_dynamic(source,
|
||||||
|
ESP32C3_INTC_DEFAULT_PRIORITY,
|
||||||
|
handler,
|
||||||
|
arg,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (source < 32) {
|
||||||
|
esp_intr_enabled_mask[0] |= (1 << source);
|
||||||
|
} else {
|
||||||
|
esp_intr_enabled_mask[1] |= (1 << (source - 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Enabled isrs -- 0: 0x%X -- 1: 0x%X",
|
||||||
|
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);
|
||||||
|
|
||||||
|
irq_unlock(key);
|
||||||
|
irq_enable(irq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp_intr_disable(int source)
|
||||||
|
{
|
||||||
|
if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t key = irq_lock();
|
||||||
|
|
||||||
|
esp_rom_intr_matrix_set(source,
|
||||||
|
source,
|
||||||
|
ESP32C3_INTC_DISABLED_SLOT);
|
||||||
|
|
||||||
|
if (source < 32) {
|
||||||
|
esp_intr_enabled_mask[0] &= ~(1 << source);
|
||||||
|
} else {
|
||||||
|
esp_intr_enabled_mask[1] &= ~(1 << (source - 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Enabled isrs -- 0: 0x%X -- 1: 0x%X",
|
||||||
|
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);
|
||||||
|
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp_intr_enable(int source)
|
||||||
|
{
|
||||||
|
if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t key = irq_lock();
|
||||||
|
uint32_t irq = esp_intr_find_irq_for_source(source);
|
||||||
|
|
||||||
|
irq_disable(irq);
|
||||||
|
esp_rom_intr_matrix_set(0, source, irq);
|
||||||
|
|
||||||
|
if (source < 32) {
|
||||||
|
esp_intr_enabled_mask[0] |= (1 << source);
|
||||||
|
} else {
|
||||||
|
esp_intr_enabled_mask[1] |= (1 << (source - 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Enabled isrs -- 0: 0x%X -- 1: 0x%X",
|
||||||
|
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);
|
||||||
|
|
||||||
|
irq_enable(irq);
|
||||||
|
irq_unlock(key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t esp_intr_get_enabled_intmask(int status_mask_number)
|
||||||
|
{
|
||||||
|
LOG_DBG("Enabled isrs -- 0: 0x%X -- 1: 0x%X",
|
||||||
|
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);
|
||||||
|
|
||||||
|
if (status_mask_number == 0) {
|
||||||
|
return esp_intr_enabled_mask[0];
|
||||||
|
} else {
|
||||||
|
return esp_intr_enabled_mask[1];
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,12 +13,11 @@
|
||||||
#include <rom/ets_sys.h>
|
#include <rom/ets_sys.h>
|
||||||
#include <esp_attr.h>
|
#include <esp_attr.h>
|
||||||
|
|
||||||
|
#include <drivers/interrupt_controller/intc_esp32c3.h>
|
||||||
#include <drivers/timer/system_timer.h>
|
#include <drivers/timer/system_timer.h>
|
||||||
#include <sys_clock.h>
|
#include <sys_clock.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
|
|
||||||
#define SYS_TIMER_CPU_IRQ 16
|
|
||||||
|
|
||||||
#define CYC_PER_TICK ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() \
|
#define CYC_PER_TICK ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() \
|
||||||
/ (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC))
|
/ (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC))
|
||||||
#define MAX_CYC 0xffffffffu
|
#define MAX_CYC 0xffffffffu
|
||||||
|
@ -45,7 +44,6 @@ static uint64_t systimer_alarm(void)
|
||||||
static void sys_timer_isr(const void *arg)
|
static void sys_timer_isr(const void *arg)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(arg);
|
ARG_UNUSED(arg);
|
||||||
|
|
||||||
systimer_ll_clear_alarm_int(SYSTIMER_ALARM_0);
|
systimer_ll_clear_alarm_int(SYSTIMER_ALARM_0);
|
||||||
|
|
||||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||||
|
@ -72,17 +70,18 @@ int sys_clock_driver_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
esp_rom_intr_matrix_set(0,
|
esp_intr_alloc(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE,
|
||||||
ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE,
|
0,
|
||||||
SYS_TIMER_CPU_IRQ);
|
sys_timer_isr,
|
||||||
IRQ_CONNECT(SYS_TIMER_CPU_IRQ, 0, sys_timer_isr, NULL, 0);
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
systimer_hal_init();
|
systimer_hal_init();
|
||||||
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
|
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
|
||||||
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
|
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
|
||||||
systimer_hal_counter_can_stall_by_cpu(SYSTIMER_COUNTER_1, 0, true);
|
systimer_hal_counter_can_stall_by_cpu(SYSTIMER_COUNTER_1, 0, true);
|
||||||
last_count = systimer_alarm();
|
last_count = systimer_alarm();
|
||||||
set_systimer_alarm(last_count + CYC_PER_TICK);
|
set_systimer_alarm(last_count + CYC_PER_TICK);
|
||||||
irq_enable(SYS_TIMER_CPU_IRQ);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
89
include/drivers/interrupt_controller/intc_esp32c3.h
Normal file
89
include/drivers/interrupt_controller/intc_esp32c3.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_DRIVERS_ESP_INTR_ALLOC_H__
|
||||||
|
#define ZEPHYR_INCLUDE_DRIVERS_ESP_INTR_ALLOC_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <soc.h>
|
||||||
|
/*
|
||||||
|
* Interrupt allocation flags - These flags can be used to specify
|
||||||
|
* which interrupt qualities the code calling esp_intr_alloc* needs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Keep the LEVELx values as they are here; they match up with (1<<level) */
|
||||||
|
#define ESP_INTR_FLAG_LEVEL1 (1<<1) /* Accept a Level 1 int vector, lowest priority */
|
||||||
|
#define ESP_INTR_FLAG_EDGE (1<<9) /* Edge-triggered interrupt */
|
||||||
|
|
||||||
|
/* Function prototype for interrupt handler function */
|
||||||
|
typedef void (*isr_handler_t)(const void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes interrupt table to its defaults
|
||||||
|
*/
|
||||||
|
void esp_intr_initialize(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate an interrupt with the given parameters.
|
||||||
|
*
|
||||||
|
* This finds an interrupt that matches the restrictions as given in the flags
|
||||||
|
* parameter, maps the given interrupt source to it and hooks up the given
|
||||||
|
* interrupt handler (with optional argument) as well. If needed, it can return
|
||||||
|
* a handle for the interrupt as well.
|
||||||
|
*
|
||||||
|
* @param source The interrupt source.
|
||||||
|
* @param flags An ORred mask of the ESP_INTR_FLAG_* defines. These restrict the
|
||||||
|
* choice of interrupts that this routine can choose from. If this value
|
||||||
|
* is 0, it will default to allocating a non-shared interrupt of level
|
||||||
|
* 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared
|
||||||
|
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
|
||||||
|
* from this function with the interrupt disabled.
|
||||||
|
* @param handler The interrupt handler.
|
||||||
|
* @param arg Optional argument for passed to the interrupt handler
|
||||||
|
* @param ret_handle Pointer to a struct intr_handle_data_t pointer to store a handle that can
|
||||||
|
* later be used to request details or free the interrupt. Can be NULL if no handle
|
||||||
|
* is required.
|
||||||
|
*
|
||||||
|
* @return -EINVAL if the combination of arguments is invalid.
|
||||||
|
* -ENODEV No free interrupt found with the specified flags
|
||||||
|
* 0 otherwise
|
||||||
|
*/
|
||||||
|
int esp_intr_alloc(int source,
|
||||||
|
int flags,
|
||||||
|
isr_handler_t handler,
|
||||||
|
void *arg,
|
||||||
|
void **ret_handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the interrupt associated with the source
|
||||||
|
*
|
||||||
|
* @param source The interrupt source
|
||||||
|
*
|
||||||
|
* @return -EINVAL if the combination of arguments is invalid.
|
||||||
|
* 0 otherwise
|
||||||
|
*/
|
||||||
|
int esp_intr_disable(int source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the interrupt associated with the source
|
||||||
|
*
|
||||||
|
* @param source The interrupt source
|
||||||
|
* @return -EINVAL if the combination of arguments is invalid.
|
||||||
|
* 0 otherwise
|
||||||
|
*/
|
||||||
|
int esp_intr_enable(int source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the current enabled interrupts
|
||||||
|
*
|
||||||
|
* @param status_mask_number the status mask can be 0 or 1
|
||||||
|
* @return bitmask of enabled interrupt sources
|
||||||
|
*/
|
||||||
|
uint32_t esp_intr_get_enabled_intmask(int status_mask_number);
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,5 +4,6 @@ zephyr_sources(
|
||||||
idle.c
|
idle.c
|
||||||
vectors.S
|
vectors.S
|
||||||
soc_irq.S
|
soc_irq.S
|
||||||
|
soc_irq.c
|
||||||
soc.c
|
soc.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ config SOC
|
||||||
default "esp32c3"
|
default "esp32c3"
|
||||||
|
|
||||||
config NUM_IRQS
|
config NUM_IRQS
|
||||||
default 32
|
default 62
|
||||||
|
|
||||||
config GEN_ISR_TABLES
|
config GEN_ISR_TABLES
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -13,18 +13,15 @@
|
||||||
#include <soc/cache_memory.h>
|
#include <soc/cache_memory.h>
|
||||||
#include "hal/soc_ll.h"
|
#include "hal/soc_ll.h"
|
||||||
#include "esp_spi_flash.h"
|
#include "esp_spi_flash.h"
|
||||||
#include <riscv/interrupt.h>
|
|
||||||
#include <soc/interrupt_reg.h>
|
#include <soc/interrupt_reg.h>
|
||||||
|
#include <drivers/interrupt_controller/intc_esp32c3.h>
|
||||||
|
|
||||||
#include <kernel_structs.h>
|
#include <kernel_structs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <toolchain/gcc.h>
|
#include <toolchain/gcc.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
|
|
||||||
#define ESP32C3_INTC_DEFAULT_PRIO 15
|
|
||||||
|
|
||||||
extern void _PrepC(void);
|
extern void _PrepC(void);
|
||||||
extern void esprv_intc_int_set_threshold(int priority_threshold);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is written in C rather than assembly since, during the port bring up,
|
* This is written in C rather than assembly since, during the port bring up,
|
||||||
|
@ -94,15 +91,15 @@ void __attribute__((section(".iram1"))) __start(void)
|
||||||
esp_rom_cache_set_idrom_mmu_size(cache_mmu_irom_size,
|
esp_rom_cache_set_idrom_mmu_size(cache_mmu_irom_size,
|
||||||
CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
|
CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
|
||||||
|
|
||||||
/* set global esp32c3's INTC masking level */
|
|
||||||
esprv_intc_int_set_threshold(1);
|
|
||||||
|
|
||||||
/* Enable wireless phy subsystem clock,
|
/* Enable wireless phy subsystem clock,
|
||||||
* This needs to be done before the kernel starts
|
* This needs to be done before the kernel starts
|
||||||
*/
|
*/
|
||||||
REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN);
|
REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN);
|
||||||
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
|
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
|
||||||
|
|
||||||
|
/*Initialize the esp32c3 interrupt controller */
|
||||||
|
esp_intr_initialize();
|
||||||
|
|
||||||
/* Start Zephyr */
|
/* Start Zephyr */
|
||||||
_PrepC();
|
_PrepC();
|
||||||
|
|
||||||
|
@ -167,24 +164,3 @@ void sys_arch_reboot(int type)
|
||||||
{
|
{
|
||||||
esp_restart_noos();
|
esp_restart_noos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_irq_enable(unsigned int irq)
|
|
||||||
{
|
|
||||||
uint32_t key = irq_lock();
|
|
||||||
|
|
||||||
esprv_intc_int_set_priority(irq, ESP32C3_INTC_DEFAULT_PRIO);
|
|
||||||
esprv_intc_int_set_type(irq, 0);
|
|
||||||
esprv_intc_int_enable(1 << irq);
|
|
||||||
|
|
||||||
irq_unlock(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arch_irq_disable(unsigned int irq)
|
|
||||||
{
|
|
||||||
esprv_intc_int_disable(1 << irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
int arch_irq_is_enabled(unsigned int irq)
|
|
||||||
{
|
|
||||||
return (REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG) & (1 << irq));
|
|
||||||
}
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ extern void esp_rom_uart_tx_wait_idle(uint8_t uart_no);
|
||||||
extern STATUS esp_rom_uart_tx_one_char(uint8_t chr);
|
extern STATUS esp_rom_uart_tx_one_char(uint8_t chr);
|
||||||
extern STATUS esp_rom_uart_rx_one_char(uint8_t *chr);
|
extern STATUS esp_rom_uart_rx_one_char(uint8_t *chr);
|
||||||
extern void esp_rom_ets_set_user_start(uint32_t start);
|
extern void esp_rom_ets_set_user_start(uint32_t start);
|
||||||
|
extern void esprv_intc_int_set_threshold(int priority_threshold);
|
||||||
|
uint32_t soc_intr_get_next_source(void);
|
||||||
|
|
||||||
#endif /* _ASMLANGUAGE */
|
#endif /* _ASMLANGUAGE */
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
/* Exports */
|
/* Exports */
|
||||||
GTEXT(__soc_is_irq)
|
GTEXT(__soc_is_irq)
|
||||||
GTEXT(__soc_handle_irq)
|
GTEXT(__soc_handle_irq)
|
||||||
|
GTEXT(soc_intr_get_next_source)
|
||||||
|
|
||||||
SECTION_FUNC(exception.other, __soc_is_irq)
|
SECTION_FUNC(exception.other, __soc_is_irq)
|
||||||
csrr a0, mcause
|
csrr a0, mcause
|
||||||
|
@ -16,4 +17,10 @@ SECTION_FUNC(exception.other, __soc_is_irq)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
SECTION_FUNC(exception.other, __soc_handle_irq)
|
SECTION_FUNC(exception.other, __soc_handle_irq)
|
||||||
|
addi sp, sp,-4
|
||||||
|
sw ra, 0x00(sp)
|
||||||
|
la t1, soc_intr_get_next_source
|
||||||
|
jalr ra, t1
|
||||||
|
lw ra, 0x00(sp)
|
||||||
|
addi sp, sp, 4
|
||||||
ret
|
ret
|
||||||
|
|
64
soc/riscv/esp32c3/soc_irq.c
Normal file
64
soc/riscv/esp32c3/soc_irq.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <soc/rtc_cntl_reg.h>
|
||||||
|
#include <soc/timer_group_reg.h>
|
||||||
|
#include <soc/gpio_reg.h>
|
||||||
|
#include <soc/syscon_reg.h>
|
||||||
|
#include <soc/system_reg.h>
|
||||||
|
#include <soc/cache_memory.h>
|
||||||
|
#include "hal/soc_ll.h"
|
||||||
|
#include <riscv/interrupt.h>
|
||||||
|
#include <soc/interrupt_reg.h>
|
||||||
|
#include <soc/periph_defs.h>
|
||||||
|
#include <drivers/interrupt_controller/intc_esp32c3.h>
|
||||||
|
|
||||||
|
#include <kernel_structs.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <toolchain/gcc.h>
|
||||||
|
#include <soc.h>
|
||||||
|
|
||||||
|
#define ESP32C3_INTC_DEFAULT_PRIO 15
|
||||||
|
#define ESP32C3_INTSTATUS_SLOT1_THRESHOLD 32
|
||||||
|
|
||||||
|
void arch_irq_enable(unsigned int irq)
|
||||||
|
{
|
||||||
|
uint32_t key = irq_lock();
|
||||||
|
|
||||||
|
esprv_intc_int_set_priority(irq, ESP32C3_INTC_DEFAULT_PRIO);
|
||||||
|
esprv_intc_int_set_type(irq, INTR_TYPE_LEVEL);
|
||||||
|
esprv_intc_int_enable(1 << irq);
|
||||||
|
irq_unlock(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_irq_disable(unsigned int irq)
|
||||||
|
{
|
||||||
|
esprv_intc_int_disable(1 << irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
int arch_irq_is_enabled(unsigned int irq)
|
||||||
|
{
|
||||||
|
return (REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG) & (1 << irq));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t soc_intr_get_next_source(void)
|
||||||
|
{
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t source;
|
||||||
|
|
||||||
|
status = REG_READ(INTERRUPT_CORE0_INTR_STATUS_0_REG) &
|
||||||
|
esp_intr_get_enabled_intmask(0);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
source = __builtin_ffs(status) - 1;
|
||||||
|
} else {
|
||||||
|
status = REG_READ(INTERRUPT_CORE0_INTR_STATUS_1_REG) &
|
||||||
|
esp_intr_get_enabled_intmask(1);
|
||||||
|
source = (__builtin_ffs(status) - 1 + ESP32C3_INTSTATUS_SLOT1_THRESHOLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue