diff --git a/arch/risc-v/include/esp32c3/irq.h b/arch/risc-v/include/esp32c3/irq.h index 5768d63001e..25e6855357f 100644 --- a/arch/risc-v/include/esp32c3/irq.h +++ b/arch/risc-v/include/esp32c3/irq.h @@ -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 diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c index ade915f0dba..fe11ebde8f5 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c +++ b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c @@ -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); } /**************************************************************************** diff --git a/arch/risc-v/src/esp32c3/esp32c3_gpio.c b/arch/risc-v/src/esp32c3/esp32c3_gpio.c index d8878817fdb..abda9e09000 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_gpio.c +++ b/arch/risc-v/src/esp32c3/esp32c3_gpio.c @@ -35,7 +35,9 @@ #include #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 diff --git a/arch/risc-v/src/esp32c3/esp32c3_i2c.c b/arch/risc-v/src/esp32c3/esp32c3_i2c.c index 49b73b606b0..49e6931da61 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_i2c.c +++ b/arch/risc-v/src/esp32c3/esp32c3_i2c.c @@ -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 diff --git a/arch/risc-v/src/esp32c3/esp32c3_irq.c b/arch/risc-v/src/esp32c3/esp32c3_irq.c index de434f7f269..d3e145d29b0 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_irq.c +++ b/arch/risc-v/src/esp32c3/esp32c3_irq.c @@ -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. */ diff --git a/arch/risc-v/src/esp32c3/esp32c3_irq.h b/arch/risc-v/src/esp32c3/esp32c3_irq.h index 3290fbf9d51..3c31367ecc7 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_irq.h +++ b/arch/risc-v/src/esp32c3/esp32c3_irq.h @@ -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 */ diff --git a/arch/risc-v/src/esp32c3/esp32c3_lowputc.c b/arch/risc-v/src/esp32c3/esp32c3_lowputc.c index a6488474083..90574ed940e 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_lowputc.c +++ b/arch/risc-v/src/esp32c3/esp32c3_lowputc.c @@ -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" diff --git a/arch/risc-v/src/esp32c3/esp32c3_lowputc.h b/arch/risc-v/src/esp32c3/esp32c3_lowputc.h index 18f6a2c474b..ac0f58b1c16 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_lowputc.h +++ b/arch/risc-v/src/esp32c3/esp32c3_lowputc.h @@ -39,11 +39,6 @@ #include "chip.h" -#include "hardware/esp32c3_uart.h" -#include "hardware/esp32c3_gpio_sigmap.h" - -#include "esp32c3_irq.h" - /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/arch/risc-v/src/esp32c3/esp32c3_serial.c b/arch/risc-v/src/esp32c3/esp32c3_serial.c index f72fae83c7f..693cfdb6483 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_serial.c +++ b/arch/risc-v/src/esp32c3/esp32c3_serial.c @@ -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; } diff --git a/arch/risc-v/src/esp32c3/esp32c3_spi.c b/arch/risc-v/src/esp32c3/esp32c3_spi.c index 30618158f2f..2e2be2975fc 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_spi.c +++ b/arch/risc-v/src/esp32c3/esp32c3_spi.c @@ -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 diff --git a/arch/risc-v/src/esp32c3/esp32c3_spi_slave.c b/arch/risc-v/src/esp32c3/esp32c3_spi_slave.c index 6e7782957b9..7eea1cd59fb 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_spi_slave.c +++ b/arch/risc-v/src/esp32c3/esp32c3_spi_slave.c @@ -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); diff --git a/arch/risc-v/src/esp32c3/esp32c3_start.c b/arch/risc-v/src/esp32c3/esp32c3_start.c index eba49d39ad7..bacf04649dd 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_start.c +++ b/arch/risc-v/src/esp32c3/esp32c3_start.c @@ -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(); diff --git a/arch/risc-v/src/esp32c3/esp32c3_tickless.c b/arch/risc-v/src/esp32c3/esp32c3_tickless.c index a1828ca8c56..15752ab0095 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_tickless.c +++ b/arch/risc-v/src/esp32c3/esp32c3_tickless.c @@ -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 */ \ No newline at end of file +#endif /* CONFIG_SCHED_TICKLESS */ diff --git a/arch/risc-v/src/esp32c3/esp32c3_tim.c b/arch/risc-v/src/esp32c3/esp32c3_tim.c index 481e59ddb87..c394e7ccc8b 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_tim.c +++ b/arch/risc-v/src/esp32c3/esp32c3_tim.c @@ -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: diff --git a/arch/risc-v/src/esp32c3/esp32c3_timerisr.c b/arch/risc-v/src/esp32c3/esp32c3_timerisr.c index fd55c04f197..9560eb9e8b3 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_timerisr.c +++ b/arch/risc-v/src/esp32c3/esp32c3_timerisr.c @@ -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); } diff --git a/arch/risc-v/src/esp32c3/esp32c3_twai.c b/arch/risc-v/src/esp32c3/esp32c3_twai.c index 585befe3771..2a70f142a66 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_twai.c +++ b/arch/risc-v/src/esp32c3/esp32c3_twai.c @@ -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; } } diff --git a/arch/risc-v/src/esp32c3/esp32c3_usbserial.c b/arch/risc-v/src/esp32c3/esp32c3_usbserial.c index 40879f126a3..fc63507ef76 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_usbserial.c +++ b/arch/risc-v/src/esp32c3/esp32c3_usbserial.c @@ -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; } diff --git a/arch/risc-v/src/esp32c3/esp32c3_wdt.c b/arch/risc-v/src/esp32c3/esp32c3_wdt.c index 4ff62b4c638..abf70e17381 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wdt.c +++ b/arch/risc-v/src/esp32c3/esp32c3_wdt.c @@ -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; } diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c index a8849741b26..baec92e4e76 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c +++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c @@ -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); } /**************************************************************************** diff --git a/arch/risc-v/src/esp32c3/esp32c3_wireless.c b/arch/risc-v/src/esp32c3/esp32c3_wireless.c index 13555e28e5a..e19ad3b10f1 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wireless.c +++ b/arch/risc-v/src/esp32c3/esp32c3_wireless.c @@ -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--;