Modify the IRQ APIs to be compatible with ESP32/S2/S3

This commit is contained in:
Alan Carvalho de Assis 2022-12-16 15:23:39 -03:00 committed by Xiang Xiao
parent f85102d81b
commit 87a1f69a3c
20 changed files with 611 additions and 287 deletions

View File

@ -29,6 +29,8 @@
* Pre-processor Definitions
****************************************************************************/
#define ESP32C3_INT_PRIO_DEF 1
/* Interrupt Matrix
*
* The Interrupt Matrix embedded in the ESP32C3 independently allocates
@ -42,26 +44,20 @@
* - Queries current interrupt status of peripheral interrupt sources.
*/
#define ESP32C3_PERIPH_WIFI_MAC 0
#define ESP32C3_PERIPH_WIFI_MAC_NMI 1
#define ESP32C3_PERIPH_WIFI_PWR 2
#define ESP32C3_PERIPH_WIFI_BB 3
#define ESP32C3_PERIPH_BT_MAC 4
#define ESP32C3_PERIPH_BT_BB 5
#define ESP32C3_PERIPH_BT_BB_NMI 6
#define ESP32C3_PERIPH_RWBT_IRQ 7
#define ESP32C3_PERIPH_RWBLE_IRQ 8
#define ESP32C3_PERIPH_RWBT_NMI 9
/* RESERVED interrupts: 0 to 14 */
#define ESP32C3_PERIPH_MAC 0 /* Reserved, but needed by WiFi driver */
#define ESP32C3_PERIPH_MAC_NMI 1 /* Reserved, but needed by WiFi driver */
#define ESP32C3_PERIPH_BT_BB 5 /* Reserved, but needed by BLE driver */
#define ESP32C3_PERIPH_RWBLE 8 /* Reserved, but needed by BLE driver */
#define ESP32C3_PERIPH_RWBLE_NMI 10
#define ESP32C3_PERIPH_I2C_MASTER 11
#define ESP32C3_PERIPH_SLC0 12
#define ESP32C3_PERIPH_SLC1 13
#define ESP32C3_PERIPH_APB_CTRL 14
#define ESP32C3_PERIPH_UHCI0 15
#define ESP32C3_PERIPH_GPIO 16
#define ESP32C3_PERIPH_GPIO_NMI 17
#define ESP32C3_PERIPH_SPI1 18
/* RESERVED interrupt 18 */
#define ESP32C3_PERIPH_SPI2 19
#define ESP32C3_PERIPH_I2S1 20
@ -75,20 +71,21 @@
#define ESP32C3_PERIPH_RMT 28
#define ESP32C3_PERIPH_I2C_EXT0 29
#define ESP32C3_PERIPH_TIMER1 30
#define ESP32C3_PERIPH_TIMER2 31
/* RESERVED interrupts 30-31 */
#define ESP32C3_PERIPH_TG0_T0 32
#define ESP32C3_PERIPH_TG0_WDT 33
#define ESP32C3_PERIPH_TG1_T0 34
#define ESP32C3_PERIPH_TG1_WDT 35
#define ESP32C3_PERIPH_CACHE_IA 36
/* RESERVED interrupt 36 */
#define ESP32C3_PERIPH_SYSTIMER_T0 37
#define ESP32C3_PERIPH_SYSTIMER_T1 38
#define ESP32C3_PERIPH_SYSTIMER_T2 39
#define ESP32C3_PERIPH_SPIMEM_REJECT_CACHE 40
#define ESP32C3_PERIPH_ICACHE_PRELOAD0 41
#define ESP32C3_PERIPH_ICACHE_SYNC0 42
/* RESERVED interrupts 40-42 */
#define ESP32C3_PERIPH_APB_ADC 43
#define ESP32C3_PERIPH_DMA_CH0 44
#define ESP32C3_PERIPH_DMA_CH1 45
@ -108,12 +105,11 @@
#define ESP32C3_PERIPH_CORE0_PIF_PMS 58
#define ESP32C3_PERIPH_CORE0_PIF_PMS_SZIE 59
#define ESP32C3_PERIPH_BAK_PMS_VIOLATE 60
#define ESP32C3_PERIPH_CACHE_CORE0_ACS 61
/* RESERVED interrupts 60-61 */
/* Total number of peripherals */
#define ESP32C3_NPERIPHERALS 62
#define ESP32C3_NPERIPHERALS 62
/* CPU Interrupts.
*
@ -123,6 +119,16 @@
#define ESP32C3_CPUINT_MIN 1
#define ESP32C3_CPUINT_MAX 31
#define ESP32C3_NCPUINTS 32
#define ESP32C3_CPUINT_MAC 0
#define ESP32C3_CPUINT_MAC_NMI 1
#define ESP32C3_CPUINT_BT_BB 5
#define ESP32C3_CPUINT_RWBLE_IRQ 8
#define ESP32C3_CPUINT_PERIPHSET 0xffffffff
/* Reserved CPU interrupt for specific drivers */
#define ESP32C3_CPUINT_WMAC 1 /* Wi-Fi MAC */
@ -136,27 +142,25 @@
#define RISCV_NIRQ_INTERRUPTS 16 /* Number of RISC-V dispatched interrupts. */
#define ESP32C3_IRQ_FIRSTPERIPH 16 /* First peripheral IRQ number */
/* IRQ numbers for peripheral interrupts coming through the Interrupt
* Matrix.
*/
#define ESP32C3_IRQ2PERIPH(irq) ((irq) - ESP32C3_IRQ_FIRSTPERIPH)
#define ESP32C3_PERIPH2IRQ(id) ((id) + ESP32C3_IRQ_FIRSTPERIPH)
/* Peripheral IRQs */
#define ESP32C3_IRQ_WIFI_MAC (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_WIFI_MAC)
#define ESP32C3_IRQ_WIFI_MAC_NMI (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_WIFI_MAC_NMI)
#define ESP32C3_IRQ_WIFI_PWR (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_WIFI_PWR)
#define ESP32C3_IRQ_WIFI_BB (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_WIFI_BB)
#define ESP32C3_IRQ_BT_MAC (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_BT_MAC)
#define ESP32C3_IRQ_MAC (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_MAC)
#define ESP32C3_IRQ_MAC_NMI (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_MAC_NMI)
#define ESP32C3_IRQ_BT_BB (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_BT_BB)
#define ESP32C3_IRQ_BT_BB_NMI (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_BT_BB_NMI)
#define ESP32C3_IRQ_RWBT_IRQ (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RWBT_IRQ)
#define ESP32C3_IRQ_RWBLE_IRQ (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RWBLE_IRQ)
#define ESP32C3_IRQ_RWBT_NMI (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RWBT_NMI)
#define ESP32C3_IRQ_RWBLE_NMI (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RWBLE_NMI)
#define ESP32C3_IRQ_I2C_MASTER (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_I2C_MASTER)
#define ESP32C3_IRQ_SLC0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SLC0)
#define ESP32C3_IRQ_SLC1 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SLC1)
#define ESP32C3_IRQ_APB_CTRL (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_APB_CTRL)
#define ESP32C3_IRQ_RWBLE (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RWBLE)
#define ESP32C3_IRQ_UHCI0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_UHCI0)
#define ESP32C3_IRQ_GPIO (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_GPIO)
#define ESP32C3_IRQ_GPIO_NMI (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_GPIO_NMI)
#define ESP32C3_IRQ_SPI1 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SPI1)
#define ESP32C3_IRQ_SPI2 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SPI2)
#define ESP32C3_IRQ_I2S1 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_I2S1)
#define ESP32C3_IRQ_UART0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_UART0)
@ -168,19 +172,16 @@
#define ESP32C3_IRQ_RTC_CORE (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RTC_CORE)
#define ESP32C3_IRQ_RMT (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_RMT)
#define ESP32C3_IRQ_I2C_EXT0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_I2C_EXT0)
#define ESP32C3_IRQ_TIMER1 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_TIMER1)
#define ESP32C3_IRQ_TIMER2 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_TIMER2)
#define ESP32C3_IRQ_TG0_T0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_TG0_T0)
#define ESP32C3_IRQ_TG0_WDT (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_TG0_WDT)
#define ESP32C3_IRQ_TG1_T0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_TG1_T0)
#define ESP32C3_IRQ_TG1_WDT (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_TG1_WDT)
#define ESP32C3_IRQ_CACHE_IA (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_CACHE_IA)
#define ESP32C3_IRQ_SYSTIMER_T0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SYSTIMER_T0)
#define ESP32C3_IRQ_SYSTIMER_T1 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SYSTIMER_T1)
#define ESP32C3_IRQ_SYSTIMER_T2 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SYSTIMER_T2)
#define ESP32C3_IRQ_SPIMEM_REJECT_CACHE (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_SPIMEM_REJECT_CACHE)
#define ESP32C3_IRQ_ICACHE_PRELOAD0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_ICACHE_PRELOAD0)
#define ESP32C3_IRQ_ICACHE_SYNC0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_ICACHE_SYNC0)
#define ESP32C3_IRQ_APB_ADC (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_APB_ADC)
#define ESP32C3_IRQ_DMA_CH0 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_DMA_CH0)
#define ESP32C3_IRQ_DMA_CH1 (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_DMA_CH1)
@ -198,8 +199,6 @@
#define ESP32C3_IRQ_CORE0_DRAM0_PMS (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_CORE0_DRAM0_PMS)
#define ESP32C3_IRQ_CORE0_PIF_PMS (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_CORE0_PIF_PMS)
#define ESP32C3_IRQ_CORE0_PIF_PMS_SZIE (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_CORE0_PIF_PMS_SZIE)
#define ESP32C3_IRQ_BAK_PMS_VIOLATE (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_BAK_PMS_VIOLATE)
#define ESP32C3_IRQ_CACHE_CORE0_ACS (ESP32C3_IRQ_FIRSTPERIPH + ESP32C3_PERIPH_CACHE_CORE0_ACS)
#define ESP32C3_NIRQ_PERIPH ESP32C3_NPERIPHERALS

View File

@ -675,7 +675,7 @@ static void interrupt_handler_set_wrapper(int n, void *fn, void *arg)
static void interrupt_on_wrapper(int intr_num)
{
up_enable_irq(intr_num);
up_enable_irq(intr_num + ESP32C3_IRQ_FIRSTPERIPH);
}
/****************************************************************************
@ -694,7 +694,7 @@ static void interrupt_on_wrapper(int intr_num)
static void interrupt_off_wrapper(int intr_num)
{
up_disable_irq(intr_num);
up_disable_irq(intr_num + ESP32C3_IRQ_FIRSTPERIPH);
}
/****************************************************************************

View File

@ -35,7 +35,9 @@
#include <arch/esp32c3/chip.h>
#include "riscv_internal.h"
#ifdef CONFIG_ESP32C3_GPIO_IRQ
#include "esp32c3_irq.h"
#endif
#include "hardware/esp32c3_iomux.h"
#include "hardware/esp32c3_gpio.h"
#include "hardware/esp32c3_usb_serial_jtag.h"
@ -326,29 +328,16 @@ void esp32c3_gpio_matrix_out(uint32_t gpio, uint32_t signal_idx,
#ifdef CONFIG_ESP32C3_GPIO_IRQ
void esp32c3_gpioirqinitialize(void)
{
int ret;
/* Setup the GPIO interrupt. */
/* Allocate a level-sensitive, priority 1 CPU interrupt */
g_gpio_cpuint = esp32c3_request_irq(ESP32C3_PERIPH_GPIO, 1,
ESP32C3_INT_LEVEL);
g_gpio_cpuint = esp32c3_setup_irq(ESP32C3_PERIPH_GPIO,
1, ESP32C3_INT_LEVEL);
DEBUGASSERT(g_gpio_cpuint > 0);
up_disable_irq(g_gpio_cpuint);
/* Attach and enable the interrupt handler */
/* Attach and enable the IRQ */
ret = irq_attach(ESP32C3_IRQ_GPIO, gpio_interrupt, NULL);
if (ret == OK)
{
up_enable_irq(g_gpio_cpuint);
}
else
{
gpioerr("ERROR: GPIO interrupt not attached!\n");
}
gpioinfo("GPIO interrupt (%d) attached.\n", g_gpio_cpuint);
DEBUGVERIFY(irq_attach(ESP32C3_IRQ_GPIO, gpio_interrupt, NULL));
up_enable_irq(ESP32C3_IRQ_GPIO);
}
#endif
@ -375,7 +364,7 @@ void esp32c3_gpioirqenable(int irq, gpio_intrtype_t intrtype)
/* Disable the GPIO interrupt during the configuration. */
up_disable_irq(g_gpio_cpuint);
up_disable_irq(ESP32C3_IRQ_GPIO);
/* Get the address of the GPIO PIN register for this pin */
@ -391,7 +380,7 @@ void esp32c3_gpioirqenable(int irq, gpio_intrtype_t intrtype)
/* Configuration done. Re-enable the GPIO interrupt. */
up_enable_irq(g_gpio_cpuint);
up_enable_irq(ESP32C3_IRQ_GPIO);
}
#endif
@ -418,14 +407,14 @@ void esp32c3_gpioirqdisable(int irq)
/* Get the address of the GPIO PIN register for this pin */
up_disable_irq(g_gpio_cpuint);
up_disable_irq(ESP32C3_IRQ_GPIO);
regaddr = GPIO_REG(pin);
regval = getreg32(regaddr);
regval &= ~(GPIO_PIN_INT_ENA_M | GPIO_PIN_INT_TYPE_M);
putreg32(regval, regaddr);
up_enable_irq(g_gpio_cpuint);
up_enable_irq(ESP32C3_IRQ_GPIO);
}
#endif

View File

@ -1485,14 +1485,15 @@ struct i2c_master_s *esp32c3_i2cbus_initialize(int port)
config = priv->config;
if (priv->cpuint != -ENOMEM)
{
/* Disable the provided CPU Interrupt to configure it. */
/* Disable the previous IRQ */
up_disable_irq(priv->cpuint);
up_disable_irq(config->irq);
esp32c3_teardown_irq(config->periph, priv->cpuint);
}
priv->cpuint = esp32c3_request_irq(config->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(config->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
/* Failed to allocate a CPU interrupt of this type. */
@ -1506,9 +1507,9 @@ struct i2c_master_s *esp32c3_i2cbus_initialize(int port)
ret = irq_attach(config->irq, esp32c3_i2c_irq, priv);
if (ret != OK)
{
/* Failed to attach IRQ, so CPU interrupt must be freed. */
/* Failed to attach IRQ, free the allocated CPU interrupt */
esp32c3_free_cpuint(config->periph);
esp32c3_teardown_irq(config->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
priv->refs--;
nxmutex_unlock(&priv->lock);
@ -1518,7 +1519,7 @@ struct i2c_master_s *esp32c3_i2cbus_initialize(int port)
/* Enable the CPU interrupt that is linked to the I2C device. */
up_enable_irq(priv->cpuint);
up_enable_irq(config->irq);
#endif
esp32c3_i2c_init(priv);
@ -1564,8 +1565,8 @@ int esp32c3_i2cbus_uninitialize(struct i2c_master_s *dev)
}
#ifndef CONFIG_I2C_POLLED
up_disable_irq(priv->cpuint);
esp32c3_free_cpuint(priv->config->periph);
up_disable_irq(priv->config->irq);
esp32c3_teardown_irq(priv->config->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
#endif

View File

@ -49,15 +49,135 @@
#define ESP32C3_DEFAULT_INT_THRESHOLD 1
/* No peripheral assigned to this CPU interrupt */
#define IRQ_UNMAPPED 0xff
#define CPUINT_UNASSIGNED 0xff
/* CPU interrupts to peripheral mapping:
*
* Encoding: EPPPPPP
* E: CPU interrupt status (0 = Disabled, 1 = Enabled).
* P: Attached peripheral.
*/
#define CPUINT_UNASSIGNED 0x3f
#define CPUINT_GETEN(m) (((m) & 0x40) >> 0x06)
#define CPUINT_GETIRQ(m) ((m) & 0x3f)
#define CPUINT_ASSIGN(c) (((c) & 0x3f) | 0x40)
#define CPUINT_DISABLE(m) ((m) & 0x3f)
#define CPUINT_ENABLE(m) ((m) | 0x40)
/* Mapping Peripheral IDs to map register addresses. */
#define CORE_MAP_REGADDR(n) (DR_REG_INTERRUPT_BASE + ((n) << 2))
/* CPU interrupts can be detached from any peripheral source by setting the
* map register to an internal CPU interrupt (1~31).
*/
#define NO_CPUINT 0
/* Priority range is 1-15 */
#define ESP32C3_MIN_PRIORITY 1
#define ESP32C3_MAX_PRIORITY 15
#define ESP32C3_PRIO_INDEX(p) ((p) - ESP32C3_MIN_PRIORITY)
#ifdef CONFIG_ESP32C3_WIFI
# define ESP32C3_WIFI_RESERVE_INT ((1 << ESP32C3_CPUINT_MAC | \
1 << ESP32C3_CPUINT_MAC_NMI))
#else
# define ESP32C3_WIFI_RESERVE_INT 0
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static uint8_t g_cpuint_map[ESP32C3_CPUINT_MAX];
/* Maps a CPU interrupt to the IRQ of the attached peripheral interrupt */
static uint8_t g_cpu_intmap[ESP32C3_NCPUINTS];
static volatile uint8_t g_irqmap[NR_IRQS];
/* Bitsets for free, unallocated CPU interrupts available to peripheral
* devices.
*/
static uint32_t g_cpu_freeints = ESP32C3_CPUINT_PERIPHSET &
(~ESP32C3_WIFI_RESERVE_INT);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: esp32c3_getcpuint
*
* Description:
* Get a free CPU interrupt for a peripheral device. This function will
* not ignore all of the pre-allocated CPU interrupts for internal
* devices.
*
* Returned Value:
* On success, a CPU interrupt number is returned.
* A negated errno is returned on failure.
*
****************************************************************************/
static int esp32c3_getcpuint(void)
{
uint32_t bitmask;
uint32_t intset;
int cpuint = 0;
int ret = -ENOMEM;
/* Check if there are CPU interrupts with the requested properties
* available.
*/
intset = g_cpu_freeints;
if (intset != 0)
{
/* Skip over initial unavailable CPU interrupts quickly in groups
* of 8 interrupt.
*/
for (cpuint = 0, bitmask = 0xff;
cpuint <= ESP32C3_CPUINT_MAX && (intset & bitmask) == 0;
cpuint += 8, bitmask <<= 8);
/* Search for an unallocated CPU interrupt number in the remaining
* intset.
*/
for (; cpuint <= ESP32C3_CPUINT_MAX; cpuint++)
{
/* If the bit corresponding to the CPU interrupt is '1', then
* that CPU interrupt is available.
*/
bitmask = 1ul << cpuint;
if ((intset & bitmask) != 0)
{
/* Got it! */
g_cpu_freeints &= ~bitmask;
ret = cpuint;
break;
}
}
}
/* Enable the CPU interrupt now. The interrupt is still not attached
* to any peripheral and thus has no effect.
*/
if (ret >= 0)
{
setbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
}
return cpuint;
}
/****************************************************************************
* Public Functions
@ -73,26 +193,24 @@ void up_irqinitialize(void)
/* Indicate that no peripheral interrupts are assigned to CPU interrupts */
memset(g_cpuint_map, CPUINT_UNASSIGNED, ESP32C3_CPUINT_MAX);
for (int i = 0; i < NR_IRQS; i++)
{
g_irqmap[i] = IRQ_UNMAPPED;
}
/**
* Initialize specific driver's CPU interrupt ID:
* Object | CPU INT | Peripheral
* | |
* Wi-Fi | 1 | 1
* BT BB | 5 | 5
* RW BLE | 8 | 8
*/
/* Hard code special cases. */
#ifdef CONFIG_ESP32C3_WIRELESS
# ifdef CONFIG_ESP32C3_WIFI
g_cpuint_map[ESP32C3_CPUINT_WMAC] = ESP32C3_PERIPH_WIFI_MAC_NMI;
# endif
#ifdef CONFIG_ESP32C3_WIFI
g_irqmap[ESP32C3_IRQ_MAC_NMI] = ESP32C3_CPUINT_MAC_NMI;
g_cpu_intmap[ESP32C3_CPUINT_MAC_NMI] = CPUINT_ASSIGN(ESP32C3_IRQ_MAC_NMI);
#endif
# ifdef CONFIG_ESP32C3_BLE
g_cpuint_map[ESP32C3_CPUINT_BT_BB] = ESP32C3_PERIPH_BT_BB;
g_cpuint_map[ESP32C3_CPUINT_RWBLE] = ESP32C3_PERIPH_RWBLE_IRQ;
# endif
#ifdef CONFIG_ESP32C3_BLE
g_irqmap[ESP32C3_IRQ_BT_BB] = ESP32C3_CPUINT_BT_BB;
g_cpu_intmap[ESP32C3_CPUINT_BT_BB] = CPUINT_ASSIGN(ESP32C3_IRQ_BT_BB);
g_irqmap[ESP32C3_IRQ_RWBLE] = ESP32C3_CPUINT_RWBLE;
g_cpu_intmap[ESP32C3_CPUINT_RWBLE] = CPUINT_ASSIGN(ESP32C3_IRQ_RWBLE);
#endif
/* Clear all peripheral interrupts from "bootloader" */
@ -128,15 +246,16 @@ void up_irqinitialize(void)
* Name: up_enable_irq
*
* Description:
* Enable the CPU interrupt specified by 'cpuint'
* Enable the interrupt specified by 'irq'
*
****************************************************************************/
void up_enable_irq(int cpuint)
void up_enable_irq(int irq)
{
int cpuint = g_irqmap[irq];
irqstate_t irqstate;
irqinfo("cpuint=%d\n", cpuint);
irqinfo("irq=%d | cpuint=%d \n", irq, cpuint);
DEBUGASSERT(cpuint >= ESP32C3_CPUINT_MIN && cpuint <= ESP32C3_CPUINT_MAX);
@ -149,23 +268,124 @@ void up_enable_irq(int cpuint)
* Name: up_disable_irq
*
* Description:
* Disable the CPU interrupt specified by 'cpuint'
* Disable the interrupt specified by 'irq'
*
****************************************************************************/
void up_disable_irq(int cpuint)
void up_disable_irq(int irq)
{
int cpuint = g_irqmap[irq];
irqinfo("irq=%d | cpuint=%d \n", irq, cpuint);
DEBUGASSERT(cpuint >= 0 && cpuint <= ESP32C3_CPUINT_MAX);
if (cpuint == IRQ_UNMAPPED)
{
/* This interrupt is already disabled. */
return;
}
else
{
irqstate_t irqstate;
g_cpu_intmap[cpuint] = CPUINT_DISABLE(g_cpu_intmap[cpuint]);
irqstate = enter_critical_section();
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
leave_critical_section(irqstate);
}
}
/****************************************************************************
* Name: esp32c3_free_cpuint
*
* Description:
* Free CPU interrupt.
*
* Input Parameters:
* periphid - Peripheral ID.
*
* Returned Value:
* None.
*
****************************************************************************/
void esp32c3_free_cpuint(uint8_t periphid)
{
irqstate_t irqstate;
uint8_t cpuint;
irqinfo("cpuint=%d\n", cpuint);
DEBUGASSERT(cpuint >= ESP32C3_CPUINT_MIN && cpuint <= ESP32C3_CPUINT_MAX);
DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS);
irqstate = enter_critical_section();
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
/* Get the CPU interrupt ID mapped to this peripheral. */
cpuint = getreg32(DR_REG_INTERRUPT_BASE + periphid * 4) & 0x1f;
irqinfo("INFO: irq[%" PRIu8 "]=%" PRIu8 "\n", periphid, cpuint);
if (cpuint != 0)
{
/* Undo the allocation process:
* 1. Unmap the peripheral from the CPU interrupt ID.
* 2. Reset the interrupt type.
* 3. Reset the interrupt priority.
* 4. Clear the CPU interrupt.
*/
DEBUGASSERT(g_cpu_intmap[cpuint] != CPUINT_UNASSIGNED);
g_cpu_intmap[cpuint] = CPUINT_UNASSIGNED;
putreg32(0, DR_REG_INTERRUPT_BASE + periphid * 4);
resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
putreg32(0, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4);
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
}
leave_critical_section(irqstate);
}
/****************************************************************************
* Name: esp32c3_cpuint_initialize
*
* Description:
* Initialize CPU interrupts
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
int esp32c3_cpuint_initialize(void)
{
/* Disable all CPU interrupts on this CPU */
for (int i = 0; i < ESP32C3_NCPUINTS; i++)
{
putreg32(0, INTERRUPT_CPU_INT_PRI_0_REG + i * 4);
}
/* Detach all interrupts from peripheral sources */
for (int i = 0; i < ESP32C3_NPERIPHERALS; i++)
{
putreg32(0, DR_REG_INTERRUPT_BASE + i * 4);
}
/* Indicate that no peripheral interrupts are assigned to CPU interrupts */
memset(g_cpu_intmap, CPUINT_UNASSIGNED, ESP32C3_NCPUINTS);
return OK;
}
/****************************************************************************
* Name: esp32c3_bind_irq
*
@ -211,127 +431,187 @@ void esp32c3_bind_irq(uint8_t cpuint, uint8_t periphid, uint8_t prio,
}
/****************************************************************************
* Name: esp32c3_request_irq
* Name: esp32c3_setup_irq
*
* Description:
* Request IRQ and resource with given parameters.
* This function sets up the IRQ. It allocates a CPU interrupt of the given
* priority and type and attaches it to the given peripheral.
*
* Input Parameters:
* periphid - Peripheral ID
* prio - Interrupt priority
* flags - Interrupt flags
* periphid - The peripheral number from irq.h to be assigned to
* a CPU interrupt.
* priority - Interrupt's priority (1 - 15).
* type - Interrupt's type (level or edge).
*
* Returned Value:
* Allocated CPU interrupt on success, a negated error on failure.
* The allocated CPU interrupt on success, a negated errno value on
* failure.
*
****************************************************************************/
int esp32c3_request_irq(uint8_t periphid, uint8_t prio, uint32_t flags)
int esp32c3_setup_irq(int periphid, int priority, int type)
{
int ret;
uint8_t cpuint;
irqstate_t irqstate;
int irq;
int cpuint;
DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS);
DEBUGASSERT((prio >= ESP32C3_INT_PRIO_MIN) &&
(prio <= ESP32C3_INT_PRIO_MAX));
irqinfo("periphid = %d\n", periphid);
irqstate = enter_critical_section();
/* Skip over already registered interrupts.
* NOTE: bit 0 is reserved for exceptions.
/* Setting up an IRQ includes the following steps:
* 1. Allocate a CPU interrupt.
* 2. Attach that CPU interrupt to the peripheral.
* 3. Map the CPU interrupt to the IRQ to ease searching later.
*/
for (cpuint = 1; cpuint <= ESP32C3_CPUINT_MAX; cpuint++)
cpuint = esp32c3_getcpuint();
if (cpuint < 0)
{
if (g_cpuint_map[cpuint] == CPUINT_UNASSIGNED)
{
break;
}
irqerr("Unable to allocate CPU interrupt for priority=%d and type=%d",
priority, type);
leave_critical_section(irqstate);
return cpuint;
}
irqinfo("periphid:%" PRIu8 " cpuint=%" PRIu8 "\n", periphid, cpuint);
irq = ESP32C3_PERIPH2IRQ(periphid);
if (cpuint <= ESP32C3_CPUINT_MAX)
{
/* We have a free CPU interrupt. We can continue with mapping the
* peripheral.
*/
DEBUGASSERT(periphid >= 0 && periphid < ESP32C3_NPERIPHERALS);
DEBUGASSERT(cpuint >= 0 && cpuint <= ESP32C3_CPUINT_MAX);
DEBUGASSERT(g_cpu_intmap[cpuint] == CPUINT_UNASSIGNED);
/* Save the CPU interrupt ID. We will return this value. */
g_cpu_intmap[cpuint] = CPUINT_ASSIGN(periphid + ESP32C3_IRQ_FIRSTPERIPH);
g_irqmap[irq] = cpuint;
ret = cpuint;
/* Update our CPU interrupt to Peripheral map. */
g_cpuint_map[cpuint] = periphid;
/* Configure IRQ */
esp32c3_bind_irq(cpuint, periphid, prio, flags);
}
else
{
/* We couldn't find a free CPU interrupt. */
ret = -ENOMEM;
}
esp32c3_bind_irq(cpuint, periphid, priority, type);
leave_critical_section(irqstate);
return ret;
return cpuint;
}
/****************************************************************************
* Name: esp32c3_free_cpuint
* Name: esp32c3_teardown_irq
*
* Description:
* Free CPU interrupt.
* This function undoes the operations done by esp32s2_setup_irq.
* It detaches a peripheral interrupt from a CPU interrupt and frees the
* CPU interrupt.
*
* Input Parameters:
* periphid - Peripheral ID.
* periphid - The peripheral number from irq.h to be detached from the
* CPU interrupt.
* cpuint - The CPU interrupt from which the peripheral interrupt will
* be detached.
*
* Returned Value:
* None.
* None
*
****************************************************************************/
void esp32c3_free_cpuint(uint8_t periphid)
void esp32c3_teardown_irq(int periphid, int cpuint)
{
irqstate_t irqstate;
uint8_t cpuint;
DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS);
uintptr_t regaddr;
int irq;
irqstate = enter_critical_section();
/* Get the CPU interrupt ID mapped to this peripheral. */
/* Tearing down an IRQ includes the following steps:
* 1. Free the previously allocated CPU interrupt.
* 2. Detach the interrupt from the peripheral.
* 3. Unmap the IRQ from the IRQ-to-cpuint map.
*/
cpuint = getreg32(DR_REG_INTERRUPT_BASE + periphid * 4) & 0x1f;
esp32c3_free_cpuint(cpuint);
irqinfo("INFO: irq[%" PRIu8 "]=%" PRIu8 "\n", periphid, cpuint);
irq = ESP32C3_PERIPH2IRQ(periphid);
if (cpuint != 0)
{
/* Undo the allocation process:
* 1. Unmap the peripheral from the CPU interrupt ID.
* 2. Reset the interrupt type.
* 3. Reset the interrupt priority.
* 4. Clear the CPU interrupt.
*/
DEBUGASSERT(periphid >= 0 && periphid < ESP32C3_NPERIPHERALS);
DEBUGASSERT(g_cpuint_map[cpuint] != CPUINT_UNASSIGNED);
DEBUGASSERT(g_cpu_intmap[cpuint] != CPUINT_UNASSIGNED);
g_cpu_intmap[cpuint] = CPUINT_UNASSIGNED;
g_irqmap[irq] = IRQ_UNMAPPED;
regaddr = CORE_MAP_REGADDR(periphid);
g_cpuint_map[cpuint] = CPUINT_UNASSIGNED;
putreg32(0, DR_REG_INTERRUPT_BASE + periphid * 4);
resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
putreg32(0, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4);
resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
}
putreg32(NO_CPUINT, regaddr);
leave_critical_section(irqstate);
}
/****************************************************************************
* Name: riscv_int_decode
*
* Description:
* Determine the peripheral that generated the interrupt and dispatch
* handling to the registered interrupt handler via riscv_irq_dispatch().
*
* Input Parameters:
* cpuints - Set of pending interrupts valid for this level
* regs - Saves processor state on the stack
*
* Returned Value:
* Normally the same value as regs is returned. But, in the event of an
* interrupt level context switch, the returned value will, instead point
* to the saved processor state in the TCB of the newly started task.
*
****************************************************************************/
#if 0
uint32_t *riscv_int_decode(uint32_t cpuints, uint32_t *regs)
{
uint32_t mask;
int bit;
#ifdef CONFIG_ARCH_LEDS_CPU_ACTIVITY
board_autoled_on(LED_CPU);
#endif
/* Skip over zero bits, eight at a time */
for (bit = 0, mask = 0xff;
bit < ESP32C3_NCPUINTS && (cpuints & mask) == 0;
bit += 8, mask <<= 8);
/* Process each pending CPU interrupt */
for (; bit < ESP32C3_NCPUINTS && cpuints != 0; bit++)
{
mask = 1 << bit;
if ((cpuints & mask) != 0)
{
/* Extract the IRQ number from the mapping table */
uint8_t irq = CPUINT_GETIRQ(g_cpu_intmap[bit]);
DEBUGASSERT(CPUINT_GETEN(g_cpu_intmap[bit]));
DEBUGASSERT(irq != CPUINT_UNASSIGNED);
/* Clear software or edge-triggered interrupt */
riscv_intclear(mask);
/* Dispatch the CPU interrupt.
*
* NOTE that regs may be altered in the case of an interrupt
* level context switch.
*/
regs = riscv_dispatch_irq((int)irq, regs);
/* Clear the bit in the pending interrupt so that perhaps
* we can exit the look early.
*/
cpuints &= ~mask;
}
}
return regs;
}
#endif
/****************************************************************************
* Name: riscv_dispatch_irq
*
@ -376,7 +656,7 @@ IRAM_ATTR uintptr_t *riscv_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
/* Clear edge interrupts. */
putreg32(1 << cpuint, INTERRUPT_CPU_INT_CLEAR_REG);
irq = g_cpuint_map[cpuint] + ESP32C3_IRQ_FIRSTPERIPH;
irq = CPUINT_GETIRQ(g_cpu_intmap[cpuint]);
}
else
{
@ -385,6 +665,8 @@ IRAM_ATTR uintptr_t *riscv_dispatch_irq(uintptr_t mcause, uintptr_t *regs)
irq = mcause;
}
irqinfo("INFO: IRQ=%d\n", irq);
regs = riscv_doirq(irq, regs);
/* Toggle the bit back to zero. */

View File

@ -33,6 +33,19 @@
* Pre-processor Definitions
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* CPU interrupt types. */
#define ESP32C3_INT_LEVEL (0 << 0)
#define ESP32C3_INT_EDGE (1 << 0)
@ -41,6 +54,10 @@
#define ESP32C3_INT_PRIO_DEF 1
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp32c3_bind_irq
*
@ -62,37 +79,68 @@ void esp32c3_bind_irq(uint8_t cpuint, uint8_t periphid, uint8_t prio,
uint32_t flags);
/****************************************************************************
* Name: esp32c3_request_irq
* Name: esp32c3_cpuint_initialize
*
* Description:
* Request IRQ and resource with given parameters.
* Initialize CPU interrupts
*
* Input Parameters:
* periphid - Peripheral ID
* prio - Interrupt priority
* flags - Interrupt flags
* None
*
* Returned Value:
* Allocated CPU interrupt on success, a negated error on failure.
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
int esp32c3_request_irq(uint8_t periphid, uint8_t prio, uint32_t flags);
int esp32c3_cpuint_initialize(void);
/****************************************************************************
* Name: esp32c3_free_cpuint
* Name: esp32c3_setup_irq
*
* Description:
* Free IRQ and resource.
* This function sets up the IRQ. It allocates a CPU interrupt of the given
* priority and type and attaches it to the given peripheral.
*
* Input Parameters:
* periphid - Peripheral ID.
* periphid - The peripheral number from irq.h to be assigned to
* a CPU interrupt.
* priority - Interrupt's priority (1 - 5).
* type - Interrupt's type (level or edge).
*
* Returned Value:
* None.
* The allocated CPU interrupt on success, a negated errno value on
* failure.
*
****************************************************************************/
void esp32c3_free_cpuint(uint8_t periphid);
int esp32c3_setup_irq(int periphid, int priority, int type);
/****************************************************************************
* Name: esp32c3_teardown_irq
*
* Description:
* This function undoes the operations done by esp32c3_setup_irq.
* It detaches a peripheral interrupt from a CPU interrupt and frees the
* CPU interrupt.
*
* Input Parameters:
* periphid - The peripheral number from irq.h to be detached from the
* CPU interrupt.
* cpuint - The CPU interrupt from which the peripheral interrupt will
* be detached.
*
* Returned Value:
* None
*
****************************************************************************/
void esp32c3_teardown_irq(int periphid, int cpuint);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_IRQ_H */

View File

@ -40,6 +40,7 @@
#include "hardware/esp32c3_system.h"
#include "hardware/esp32c3_uart.h"
#include "hardware/esp32c3_soc.h"
#include "hardware/esp32c3_gpio_sigmap.h"
#include "esp32c3_clockconfig.h"
#include "esp32c3_config.h"

View File

@ -39,11 +39,6 @@
#include "chip.h"
#include "hardware/esp32c3_uart.h"
#include "hardware/esp32c3_gpio_sigmap.h"
#include "esp32c3_irq.h"
/****************************************************************************
* Public Types
****************************************************************************/

View File

@ -464,10 +464,10 @@ static int esp32c3_attach(struct uart_dev_s *dev)
DEBUGASSERT(priv->cpuint == -ENOMEM);
/* Try to attach the IRQ to a CPU int */
/* Set up to receive peripheral interrupts */
priv->cpuint = esp32c3_request_irq(priv->periph, priv->int_pri,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(priv->periph, priv->int_pri,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
return priv->cpuint;
@ -478,11 +478,11 @@ static int esp32c3_attach(struct uart_dev_s *dev)
ret = irq_attach(priv->irq, uart_handler, dev);
if (ret == OK)
{
up_enable_irq(priv->cpuint);
up_enable_irq(priv->irq);
}
else
{
up_disable_irq(priv->cpuint);
up_disable_irq(priv->irq);
}
return ret;
@ -507,9 +507,14 @@ static void esp32c3_detach(struct uart_dev_s *dev)
DEBUGASSERT(priv->cpuint != -ENOMEM);
up_disable_irq(priv->cpuint);
/* Disable and detach the CPU interrupt */
up_disable_irq(priv->irq);
irq_detach(priv->irq);
esp32c3_free_cpuint(priv->periph);
/* Disassociate the peripheral interrupt from the CPU interrupt */
esp32c3_teardown_irq(priv->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
}

View File

@ -1385,12 +1385,12 @@ struct spi_dev_s *esp32c3_spibus_initialize(int port)
{
/* Disable the provided CPU Interrupt to configure it. */
up_disable_irq(priv->cpuint);
up_disable_irq(priv->config->irq);
}
priv->cpuint = esp32c3_request_irq(priv->config->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(priv->config->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
/* Failed to allocate a CPU interrupt of this type. */
@ -1403,7 +1403,7 @@ struct spi_dev_s *esp32c3_spibus_initialize(int port)
{
/* Failed to attach IRQ, so CPU interrupt must be freed. */
esp32c3_free_cpuint(priv->config->periph);
esp32c3_teardown_irq(priv->config->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
nxmutex_unlock(&priv->lock);
@ -1412,7 +1412,7 @@ struct spi_dev_s *esp32c3_spibus_initialize(int port)
/* Enable the CPU interrupt that is linked to the SPI device. */
up_enable_irq(priv->cpuint);
up_enable_irq(priv->config->irq);
#endif
esp32c3_spi_init(spi_dev);
@ -1455,8 +1455,8 @@ int esp32c3_spibus_uninitialize(struct spi_dev_s *dev)
}
#ifdef CONFIG_ESP32C3_SPI2_DMA
up_disable_irq(priv->cpuint);
esp32c3_free_cpuint(priv->config->periph);
up_disable_irq(priv->config->irq);
esp32c3_free_cpuint(priv->config->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
#endif

View File

@ -1148,7 +1148,7 @@ static void spislave_bind(struct spi_slave_ctrlr_s *ctrlr,
/* Enable the CPU interrupt that is linked to the SPI Slave controller */
up_enable_irq(priv->cpuint);
up_enable_irq(priv->config->irq);
leave_critical_section(flags);
}
@ -1181,7 +1181,7 @@ static void spislave_unbind(struct spi_slave_ctrlr_s *ctrlr)
flags = enter_critical_section();
up_disable_irq(priv->cpuint);
up_disable_irq(priv->config->irq);
esp32c3_gpioirqdisable(ESP32C3_PIN2IRQ(priv->config->cs_pin));
@ -1437,12 +1437,12 @@ struct spi_slave_ctrlr_s *esp32c3_spislave_ctrlr_initialize(int port)
{
/* Disable the provided CPU Interrupt to configure it. */
up_disable_irq(priv->cpuint);
up_disable_irq(priv->config->irq);
}
priv->cpuint = esp32c3_request_irq(priv->config->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(priv->config->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
/* Failed to allocate a CPU interrupt of this type. */
@ -1456,7 +1456,7 @@ struct spi_slave_ctrlr_s *esp32c3_spislave_ctrlr_initialize(int port)
{
/* Failed to attach IRQ, so CPU interrupt must be freed. */
esp32c3_free_cpuint(priv->config->periph);
esp32c3_teardown_irq(priv->config->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
leave_critical_section(flags);
@ -1504,8 +1504,8 @@ int esp32c3_spislave_ctrlr_uninitialize(struct spi_slave_ctrlr_s *ctrlr)
return OK;
}
up_disable_irq(priv->cpuint);
esp32c3_free_cpuint(priv->config->periph);
up_disable_irq(priv->config->irq);
esp32c3_teardown_irq(priv->config->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
spislave_deinitialize(ctrlr);

View File

@ -253,6 +253,12 @@ void __esp32c3_start(void)
esp32c3_region_protection();
#endif
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* Put the CPU Interrupts in initial state */
esp32c3_cpuint_initialize();
#endif
/* Initialize RTC parameters */
esp32c3_rtc_init();

View File

@ -489,8 +489,6 @@ int IRAM_ATTR up_timer_start(const struct timespec *ts)
void up_timer_initialize(void)
{
int cpuint;
g_timer_started = false;
/* Enable timer clock */
@ -510,9 +508,9 @@ void up_timer_initialize(void)
/* Attach the timer interrupt */
cpuint = esp32c3_request_irq(ESP32C3_PERIPH_SYSTIMER_T0,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
esp32c3_setup_irq(ESP32C3_PERIPH_SYSTIMER_T0,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
/* Attach the timer interrupt. */
@ -520,7 +518,7 @@ void up_timer_initialize(void)
/* Enable the allocated CPU interrupt. */
up_enable_irq(cpuint);
up_enable_irq(ESP32C3_IRQ_SYSTIMER_T0);
}
/****************************************************************************
@ -605,4 +603,4 @@ void IRAM_ATTR up_step_idletime(uint32_t us)
leave_critical_section(flags);
}
#endif /* CONFIG_SCHED_TICKLESS */
#endif /* CONFIG_SCHED_TICKLESS */

View File

@ -46,11 +46,11 @@
struct esp32c3_tim_priv_s
{
struct esp32c3_tim_ops_s *ops;
uint8_t id; /* Timer instance */
uint8_t periph; /* Peripheral ID */
uint8_t irq; /* Interrupt ID */
int cpuint; /* CPU interrupt assigned to this timer */
bool inuse; /* Flag indicating if the timer is in use */
uint8_t id; /* Timer instance */
uint8_t periph; /* Peripheral ID */
uint8_t irq; /* Interrupt ID */
int cpuint; /* CPU interrupt assigned to this timer */
bool inuse; /* Flag indicating if the timer is in use */
};
/****************************************************************************
@ -702,19 +702,22 @@ static int esp32c3_tim_setisr(struct esp32c3_tim_dev_s *dev,
if (handler == NULL)
{
/* If a CPU Interrupt was previously allocated, then deallocate it */
if (priv->cpuint != -ENOMEM)
{
/* Disable cpu interrupt */
up_disable_irq(priv->cpuint);
/* Dissociate the IRQ from the ISR */
/* Disable CPU Interrupt, free a previously allocated
* CPU Interrupt
*/
up_disable_irq(priv->irq);
esp32c3_teardown_irq(priv->periph, priv->cpuint);
irq_detach(priv->irq);
/* Free cpu interrupt that is attached to this peripheral */
esp32c3_free_cpuint(priv->periph);
priv->cpuint = -ENOMEM;
}
}
@ -725,24 +728,18 @@ static int esp32c3_tim_setisr(struct esp32c3_tim_dev_s *dev,
{
if (priv->cpuint != -ENOMEM)
{
/* Disable the provided CPU interrupt to configure it. */
/* Disable the previous IRQ */
up_disable_irq(priv->cpuint);
/* Free cpu interrupt that is attached to this peripheral
* because we will get another from esp32c3_request_irq()
*/
esp32c3_free_cpuint(priv->periph);
up_disable_irq(priv->irq);
}
priv->cpuint = esp32c3_request_irq(priv->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(priv->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
tmrerr("ERROR: Failed to get a CPU interrupt");
tmrerr("ERROR: No CPU interrupt available");
ret = priv->cpuint;
goto errout;
}
@ -753,13 +750,13 @@ static int esp32c3_tim_setisr(struct esp32c3_tim_dev_s *dev,
if (ret != OK)
{
tmrerr("ERROR: Failed to associate an IRQ Number to and ISR");
esp32c3_free_cpuint(priv->periph);
esp32c3_teardown_irq(priv->periph, priv->cpuint);
goto errout;
}
/* Enable the CPU Interrupt that is linked to the timer */
up_enable_irq(priv->cpuint);
up_enable_irq(priv->irq);
}
errout:

View File

@ -78,7 +78,6 @@ static int systimer_isr(int irq, void *context, void *arg)
void up_timer_initialize(void)
{
uint32_t regval;
int cpuint;
/* Enable timer clock */
@ -113,9 +112,9 @@ void up_timer_initialize(void)
regval = SYS_TIMER_TIMER_UNIT0_WORK_EN;
setbits(regval, SYS_TIMER_SYSTIMER_CONF_REG);
cpuint = esp32c3_request_irq(ESP32C3_PERIPH_SYSTIMER_T0,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
esp32c3_setup_irq(ESP32C3_PERIPH_SYSTIMER_T0,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
/* Attach the timer interrupt. */
@ -123,5 +122,5 @@ void up_timer_initialize(void)
/* Enable the allocated CPU interrupt. */
up_enable_irq(cpuint);
up_enable_irq(ESP32C3_IRQ_SYSTIMER_T0);
}

View File

@ -451,12 +451,12 @@ static int esp32c3twai_setup(struct can_dev_s *dev)
{
/* Disable the provided CPU Interrupt to configure it. */
up_disable_irq(priv->cpuint);
up_disable_irq(priv->irq);
}
priv->cpuint = esp32c3_request_irq(priv->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(priv->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
/* Failed to allocate a CPU interrupt of this type. */
@ -472,7 +472,7 @@ static int esp32c3twai_setup(struct can_dev_s *dev)
{
/* Failed to attach IRQ, so CPU interrupt must be freed. */
esp32c3_free_cpuint(priv->periph);
esp32c3_teardown_irq(priv->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
leave_critical_section(flags);
@ -481,7 +481,7 @@ static int esp32c3twai_setup(struct can_dev_s *dev)
/* Enable the CPU interrupt that is linked to the TWAI device. */
up_enable_irq(priv->cpuint);
up_enable_irq(priv->irq);
leave_critical_section(flags);
@ -515,7 +515,7 @@ static void esp32c3twai_shutdown(struct can_dev_s *dev)
{
/* Disable cpu interrupt */
up_disable_irq(priv->cpuint);
up_disable_irq(priv->irq);
/* Dissociate the IRQ from the ISR */
@ -523,7 +523,7 @@ static void esp32c3twai_shutdown(struct can_dev_s *dev)
/* Free cpu interrupt that is attached to this peripheral */
esp32c3_free_cpuint(priv->periph);
esp32c3_teardown_irq(priv->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
}
}

View File

@ -276,9 +276,9 @@ static int esp32c3_attach(struct uart_dev_s *dev)
/* Try to attach the IRQ to a CPU int */
priv->cpuint = esp32c3_request_irq(priv->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(priv->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
if (priv->cpuint < 0)
{
return priv->cpuint;
@ -289,11 +289,11 @@ static int esp32c3_attach(struct uart_dev_s *dev)
ret = irq_attach(priv->irq, esp32c3_interrupt, dev);
if (ret == OK)
{
up_enable_irq(priv->cpuint);
up_enable_irq(priv->irq);
}
else
{
up_disable_irq(priv->cpuint);
up_disable_irq(priv->irq);
}
return ret;
@ -315,9 +315,9 @@ static void esp32c3_detach(struct uart_dev_s *dev)
DEBUGASSERT(priv->cpuint != -ENOMEM);
up_disable_irq(priv->cpuint);
up_disable_irq(priv->irq);
irq_detach(priv->irq);
esp32c3_free_cpuint(priv->periph);
esp32c3_teardown_irq(priv->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
}

View File

@ -746,7 +746,7 @@ static int32_t esp32c3_wdt_setisr(struct esp32c3_wdt_dev_s *dev,
up_disable_irq(wdt->cpuint);
irq_detach(wdt->irq);
esp32c3_free_cpuint(wdt->periph);
esp32c3_teardown_irq(wdt->periph, wdt->cpuint);
wdt->cpuint = -ENOMEM;
}
}
@ -762,13 +762,13 @@ static int32_t esp32c3_wdt_setisr(struct esp32c3_wdt_dev_s *dev,
up_disable_irq(wdt->cpuint);
/* Free CPU interrupt that is attached to this peripheral
* because we will get another from esp32c3_request_irq()
* because we will get another from esp32c3_setup_irq()
*/
esp32c3_free_cpuint(wdt->periph);
esp32c3_teardown_irq(wdt->periph, wdt->cpuint);
}
wdt->cpuint = esp32c3_request_irq(wdt->periph,
wdt->cpuint = esp32c3_setup_irq(wdt->periph,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
@ -784,7 +784,7 @@ static int32_t esp32c3_wdt_setisr(struct esp32c3_wdt_dev_s *dev,
{
/* Failed to attach IRQ, so CPU interrupt must be freed. */
esp32c3_free_cpuint(wdt->periph);
esp32c3_teardown_irq(wdt->periph, wdt->cpuint);
wdt->cpuint = -ENOMEM;
return ret;
}

View File

@ -980,7 +980,9 @@ static void esp32c3_ints_on(uint32_t mask)
{
int n = __builtin_ffs(mask) - 1;
up_enable_irq(n);
wlinfo("INFO mask=%08lx irq=%d\n", mask, n);
up_enable_irq(ESP32C3_IRQ_MAC_NMI);
}
/****************************************************************************
@ -1001,7 +1003,9 @@ static void esp32c3_ints_off(uint32_t mask)
{
int n = __builtin_ffs(mask) - 1;
up_disable_irq(n);
wlinfo("INFO mask=%08lx irq=%d\n", mask, n);
up_disable_irq(ESP32C3_IRQ_MAC_NMI);
}
/****************************************************************************

View File

@ -445,14 +445,14 @@ int esp32c3_wl_init(void)
return OK;
}
priv->cpuint = esp32c3_request_irq(SWI_PERIPH,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
priv->cpuint = esp32c3_setup_irq(SWI_PERIPH,
ESP32C3_INT_PRIO_DEF,
ESP32C3_INT_LEVEL);
ret = irq_attach(SWI_IRQ, esp32c3_wl_swi_irq, NULL);
if (ret < 0)
{
esp32c3_free_cpuint(SWI_PERIPH);
esp32c3_teardown_irq(SWI_PERIPH, priv->cpuint);
leave_critical_section(flags);
wlerr("ERROR: Failed to attach IRQ ret=%d\n", ret);
@ -461,7 +461,7 @@ int esp32c3_wl_init(void)
list_initialize(&priv->sc_list);
up_enable_irq(priv->cpuint);
up_enable_irq(SWI_IRQ);
priv->ref++;
@ -497,9 +497,9 @@ int esp32c3_wl_deinit(void)
return OK;
}
up_disable_irq(priv->cpuint);
up_disable_irq(SWI_IRQ);
irq_detach(SWI_IRQ);
esp32c3_free_cpuint(SWI_PERIPH);
esp32c3_teardown_irq(SWI_PERIPH, priv->cpuint);
priv->ref--;