mirror of
https://github.com/apache/nuttx.git
synced 2026-06-08 01:42:58 +08:00
ESP32: Add CPU interrupt managmement logic; improve level interrupt decoding.
This commit is contained in:
+264
-96
@@ -50,29 +50,6 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Exceptions
|
||||
*
|
||||
* IRAM Offset Description
|
||||
* 0x0000 Windows
|
||||
* 0x0180 Level 2 interrupt
|
||||
* 0x01c0 Level 3 interrupt
|
||||
* 0x0200 Level 4 interrupt
|
||||
* 0x0240 Level 5 interrupt
|
||||
* 0x0280 Debug exception
|
||||
* 0x02c0 NMI exception
|
||||
* 0x0300 Kernel exception
|
||||
* 0x0340 User exception
|
||||
* 0x03c0 Double exception
|
||||
*
|
||||
* REVISIT: In more architectures supported by NuttX, exception errors
|
||||
* tie into the normal interrupt handling via special IRQ numbers. I
|
||||
* is still to be determined what will be done for the ESP32.
|
||||
*/
|
||||
|
||||
#define XTENSA_IRQ_TIMER0 0 /* INTERRUPT, bit 6 */
|
||||
#define XTENSA_IRQ_TIMER1 1 /* INTERRUPT, bit 15 */
|
||||
#define XTENSA_IRQ_TIMER2 2 /* INTERRUPT, bit 16 */
|
||||
|
||||
/* Interrupt Matrix
|
||||
*
|
||||
* The Interrupt Matrix embedded in the ESP32 independently allocates
|
||||
@@ -102,94 +79,285 @@
|
||||
|
||||
/* PRO_INTR_STATUS_REG_0 / APP_INTR_STATUS_REG_0 */
|
||||
|
||||
#define XTENSA_IRQ_SREG0 3
|
||||
#define XTENSA_IRQ_MAC 3 /* INTR_STATUS_REG_0, bit 0 */
|
||||
#define XTENSA_IRQ_MAC_NMI 4 /* INTR_STATUS_REG_0, bit 1 */
|
||||
#define XTENSA_IRQ_BB 5 /* INTR_STATUS_REG_0, bit 2 */
|
||||
#define XTENSA_IRQ_BB_MAC 6 /* INTR_STATUS_REG_0, bit 3 */
|
||||
#define XTENSA_IRQ_BT_BB 7 /* INTR_STATUS_REG_0, bit 4 */
|
||||
#define XTENSA_IRQ_BT_BB_NMI 8 /* INTR_STATUS_REG_0, bit 5 */
|
||||
#define XTENSA_IRQ_RWBT_IRQ 9 /* INTR_STATUS_REG_0, bit 6 */
|
||||
#define XTENSA_IRQ_RWBLE_IRQ 10 /* INTR_STATUS_REG_0, bit 7 */
|
||||
#define XTENSA_IRQ_RWBT_NMI 11 /* INTR_STATUS_REG_0, bit 8 */
|
||||
#define XTENSA_IRQ_RWBLE_NMI 12 /* INTR_STATUS_REG_0, bit 9 */
|
||||
#define ESP32_PERIPH_MAC 0 /* INTR_STATUS_REG_0, bit 0 */
|
||||
#define ESP32_PERIPH_MAC_NMI 1 /* INTR_STATUS_REG_0, bit 1 */
|
||||
#define ESP32_PERIPH_BB 2 /* INTR_STATUS_REG_0, bit 2 */
|
||||
#define ESP32_PERIPH_BB_MAC 3 /* INTR_STATUS_REG_0, bit 3 */
|
||||
#define ESP32_PERIPH_BT_BB 4 /* INTR_STATUS_REG_0, bit 4 */
|
||||
#define ESP32_PERIPH_BT_BB_NMI 5 /* INTR_STATUS_REG_0, bit 5 */
|
||||
#define ESP32_PERIPH_RWBT_IRQ 6 /* INTR_STATUS_REG_0, bit 6 */
|
||||
#define ESP32_PERIPH_RWBLE_IRQ 7 /* INTR_STATUS_REG_0, bit 7 */
|
||||
#define ESP32_PERIPH_RWBT_NMI 8 /* INTR_STATUS_REG_0, bit 8 */
|
||||
#define ESP32_PERIPH_RWBLE_NMI 9 /* INTR_STATUS_REG_0, bit 9 */
|
||||
|
||||
#define XTENSA_IRQ_SLC0 13 /* INTR_STATUS_REG_0, bit 10 */
|
||||
#define XTENSA_IRQ_SLC1 14 /* INTR_STATUS_REG_0, bit 11 */
|
||||
#define XTENSA_IRQ_UHCI0 15 /* INTR_STATUS_REG_0, bit 12 */
|
||||
#define XTENSA_IRQ_UHCI1 16 /* INTR_STATUS_REG_0, bit 13 */
|
||||
#define XTENSA_IRQ_TG_T0_LEVEL 17 /* INTR_STATUS_REG_0, bit 14 */
|
||||
#define XTENSA_IRQ_TG_T1_LEVEL 18 /* INTR_STATUS_REG_0, bit 15 */
|
||||
#define XTENSA_IRQ_TG_WDT_LEVEL 19 /* INTR_STATUS_REG_0, bit 16 */
|
||||
#define XTENSA_IRQ_TG_LACT_LEVEL 20 /* INTR_STATUS_REG_0, bit 17 */
|
||||
#define XTENSA_IRQ_TG1_T0_LEVEL 21 /* INTR_STATUS_REG_0, bit 18 */
|
||||
#define XTENSA_IRQ_TG1_T1_LEVEL 22 /* INTR_STATUS_REG_0, bit 19 */
|
||||
#define ESP32_PERIPH_SLC0 10 /* INTR_STATUS_REG_0, bit 10 */
|
||||
#define ESP32_PERIPH_SLC1 11 /* INTR_STATUS_REG_0, bit 11 */
|
||||
#define ESP32_PERIPH_UHCI0 12 /* INTR_STATUS_REG_0, bit 12 */
|
||||
#define ESP32_PERIPH_UHCI1 13 /* INTR_STATUS_REG_0, bit 13 */
|
||||
#define ESP32_PERIPH_TG_T0_LEVEL 14 /* INTR_STATUS_REG_0, bit 14 */
|
||||
#define ESP32_PERIPH_TG_T1_LEVEL 15 /* INTR_STATUS_REG_0, bit 15 */
|
||||
#define ESP32_PERIPH_TG_WDT_LEVEL 16 /* INTR_STATUS_REG_0, bit 16 */
|
||||
#define ESP32_PERIPH_TG_LACT_LEVEL 17 /* INTR_STATUS_REG_0, bit 17 */
|
||||
#define ESP32_PERIPH_TG1_T0_LEVEL 18 /* INTR_STATUS_REG_0, bit 18 */
|
||||
#define ESP32_PERIPH_TG1_T1_LEVEL 19 /* INTR_STATUS_REG_0, bit 19 */
|
||||
|
||||
#define XTENSA_IRQ_TG1_WDT_LEVEL 23 /* INTR_STATUS_REG_0, bit 20 */
|
||||
#define XTENSA_IRQ_G1_LACT_LEVEL 24 /* INTR_STATUS_REG_0, bit 21 */
|
||||
#define XTENSA_IRQ_CPU_GPIO 25 /* INTR_STATUS_REG_0, bit 22 */
|
||||
#define XTENSA_IRQ_CPU_NMI 26 /* INTR_STATUS_REG_0, bit 23 */
|
||||
#define XTENSA_IRQ_CPU_CPU0 27 /* INTR_STATUS_REG_0, bit 24 */
|
||||
#define XTENSA_IRQ_CPU_CPU1 28 /* INTR_STATUS_REG_0, bit 25 */
|
||||
#define XTENSA_IRQ_CPU_CPU2 29 /* INTR_STATUS_REG_0, bit 26 */
|
||||
#define XTENSA_IRQ_CPU_CPU3 30 /* INTR_STATUS_REG_0, bit 27 */
|
||||
#define XTENSA_IRQ_SPI0 31 /* INTR_STATUS_REG_0, bit 28 */
|
||||
#define XTENSA_IRQ_SPI1 32 /* INTR_STATUS_REG_0, bit 29 */
|
||||
#define ESP32_PERIPH_TG1_WDT_LEVEL 20 /* INTR_STATUS_REG_0, bit 20 */
|
||||
#define ESP32_PERIPH_G1_LACT_LEVEL 21 /* INTR_STATUS_REG_0, bit 21 */
|
||||
#define ESP32_PERIPH_CPU_GPIO 22 /* INTR_STATUS_REG_0, bit 22 */
|
||||
#define ESP32_PERIPH_CPU_NMI 23 /* INTR_STATUS_REG_0, bit 23 */
|
||||
#define ESP32_PERIPH_CPU_CPU0 24 /* INTR_STATUS_REG_0, bit 24 */
|
||||
#define ESP32_PERIPH_CPU_CPU1 25 /* INTR_STATUS_REG_0, bit 25 */
|
||||
#define ESP32_PERIPH_CPU_CPU2 26 /* INTR_STATUS_REG_0, bit 26 */
|
||||
#define ESP32_PERIPH_CPU_CPU3 27 /* INTR_STATUS_REG_0, bit 27 */
|
||||
#define ESP32_PERIPH_SPI0 28 /* INTR_STATUS_REG_0, bit 28 */
|
||||
#define ESP32_PERIPH_SPI1 29 /* INTR_STATUS_REG_0, bit 29 */
|
||||
|
||||
#define XTENSA_IRQ_SPI2 33 /* INTR_STATUS_REG_0, bit 30 */
|
||||
#define XTENSA_IRQ_SPI3 34 /* INTR_STATUS_REG_0, bit 31 */
|
||||
#define ESP32_PERIPH_SPI2 30 /* INTR_STATUS_REG_0, bit 30 */
|
||||
#define ESP32_PERIPH_SPI3 31 /* INTR_STATUS_REG_0, bit 31 */
|
||||
|
||||
/* PRO_INTR_STATUS_REG_1 / APP_INTR_STATUS_REG_1 */
|
||||
|
||||
#define XTENSA_IRQ_SREG1 35
|
||||
#define XTENSA_IRQ_I2S0 35 /* INTR_STATUS_REG_1, bit 0 */
|
||||
#define XTENSA_IRQ_I2S1 36 /* INTR_STATUS_REG_1, bit 1 */
|
||||
#define XTENSA_IRQ_UART 37 /* INTR_STATUS_REG_1, bit 2 */
|
||||
#define XTENSA_IRQ_UART1 38 /* INTR_STATUS_REG_1, bit 3 */
|
||||
#define XTENSA_IRQ_UART2 39 /* INTR_STATUS_REG_1, bit 4 */
|
||||
#define XTENSA_IRQ_SDIO_HOST 40 /* INTR_STATUS_REG_1, bit 5 */
|
||||
#define XTENSA_IRQ_EMAC 41 /* INTR_STATUS_REG_1, bit 6 */
|
||||
#define XTENSA_IRQ_PWM0 42 /* INTR_STATUS_REG_1, bit 7 */
|
||||
#define XTENSA_IRQ_PWM1 43 /* INTR_STATUS_REG_1, bit 8 */
|
||||
#define XTENSA_IRQ_PWM2 44 /* INTR_STATUS_REG_1, bit 9 */
|
||||
#define ESP32_PERIPH_I2S0 32 /* INTR_STATUS_REG_1, bit 0 */
|
||||
#define ESP32_PERIPH_I2S1 33 /* INTR_STATUS_REG_1, bit 1 */
|
||||
#define ESP32_PERIPH_UART 34 /* INTR_STATUS_REG_1, bit 2 */
|
||||
#define ESP32_PERIPH_UART1 35 /* INTR_STATUS_REG_1, bit 3 */
|
||||
#define ESP32_PERIPH_UART2 36 /* INTR_STATUS_REG_1, bit 4 */
|
||||
#define ESP32_PERIPH_SDIO_HOST 37 /* INTR_STATUS_REG_1, bit 5 */
|
||||
#define ESP32_PERIPH_EMAC 38 /* INTR_STATUS_REG_1, bit 6 */
|
||||
#define ESP32_PERIPH_PWM0 39 /* INTR_STATUS_REG_1, bit 7 */
|
||||
#define ESP32_PERIPH_PWM1 40 /* INTR_STATUS_REG_1, bit 8 */
|
||||
#define ESP32_PERIPH_PWM2 41 /* INTR_STATUS_REG_1, bit 9 */
|
||||
|
||||
#define XTENSA_IRQ_PWM3 45 /* INTR_STATUS_REG_1, bit 10 */
|
||||
#define XTENSA_IRQ_LEDC 46 /* INTR_STATUS_REG_1, bit 11 */
|
||||
#define XTENSA_IRQ_EFUSE 47 /* INTR_STATUS_REG_1, bit 12 */
|
||||
#define XTENSA_IRQ_CAN 48 /* INTR_STATUS_REG_1, bit 13 */
|
||||
#define XTENSA_IRQ_RTC_CORE 49 /* INTR_STATUS_REG_1, bit 14 */
|
||||
#define XTENSA_IRQ_RMT 50 /* INTR_STATUS_REG_1, bit 15 */
|
||||
#define XTENSA_IRQ_PCNT 51 /* INTR_STATUS_REG_1, bit 16 */
|
||||
#define XTENSA_IRQ_I2C_EXT0 52 /* INTR_STATUS_REG_1, bit 17 */
|
||||
#define XTENSA_IRQ_I2C_EXT1 53 /* INTR_STATUS_REG_1, bit 18 */
|
||||
#define XTENSA_IRQ_RSA 54 /* INTR_STATUS_REG_1, bit 19 */
|
||||
#define ESP32_PERIPH_PWM3 42 /* INTR_STATUS_REG_1, bit 10 */
|
||||
#define ESP32_PERIPH_LEDC 43 /* INTR_STATUS_REG_1, bit 11 */
|
||||
#define ESP32_PERIPH_EFUSE 44 /* INTR_STATUS_REG_1, bit 12 */
|
||||
#define ESP32_PERIPH_CAN 45 /* INTR_STATUS_REG_1, bit 13 */
|
||||
#define ESP32_PERIPH_RTC_CORE 46 /* INTR_STATUS_REG_1, bit 14 */
|
||||
#define ESP32_PERIPH_RMT 47 /* INTR_STATUS_REG_1, bit 15 */
|
||||
#define ESP32_PERIPH_PCNT 48 /* INTR_STATUS_REG_1, bit 16 */
|
||||
#define ESP32_PERIPH_I2C_EXT0 49 /* INTR_STATUS_REG_1, bit 17 */
|
||||
#define ESP32_PERIPH_I2C_EXT1 50 /* INTR_STATUS_REG_1, bit 18 */
|
||||
#define ESP32_PERIPH_RSA 51 /* INTR_STATUS_REG_1, bit 19 */
|
||||
|
||||
#define XTENSA_IRQ_SPI1_DMA 55 /* INTR_STATUS_REG_1, bit 20 */
|
||||
#define XTENSA_IRQ_SPI2_DMA 56 /* INTR_STATUS_REG_1, bit 21 */
|
||||
#define XTENSA_IRQ_SPI3_DMA 57 /* INTR_STATUS_REG_1, bit 22 */
|
||||
#define XTENSA_IRQ_WDG 58 /* INTR_STATUS_REG_1, bit 23 */
|
||||
#define XTENSA_IRQ_TIMER1 59 /* INTR_STATUS_REG_1, bit 24 */
|
||||
#define XTENSA_IRQ_TIMER2 60 /* INTR_STATUS_REG_1, bit 25 */
|
||||
#define XTENSA_IRQ_TG_T0_EDGE 61 /* INTR_STATUS_REG_1, bit 26 */
|
||||
#define XTENSA_IRQ_TG_T1_EDGE 62 /* INTR_STATUS_REG_1, bit 27 */
|
||||
#define XTENSA_IRQ_TG_WDT_EDGE 63 /* INTR_STATUS_REG_1, bit 28 */
|
||||
#define XTENSA_IRQ_TG_LACT_EDGE 64 /* INTR_STATUS_REG_1, bit 29 */
|
||||
#define ESP32_PERIPH_SPI1_DMA 52 /* INTR_STATUS_REG_1, bit 20 */
|
||||
#define ESP32_PERIPH_SPI2_DMA 53 /* INTR_STATUS_REG_1, bit 21 */
|
||||
#define ESP32_PERIPH_SPI3_DMA 54 /* INTR_STATUS_REG_1, bit 22 */
|
||||
#define ESP32_PERIPH_WDG 55 /* INTR_STATUS_REG_1, bit 23 */
|
||||
#define ESP32_PERIPH_TIMER1 56 /* INTR_STATUS_REG_1, bit 24 */
|
||||
#define ESP32_PERIPH_TIMER2 57 /* INTR_STATUS_REG_1, bit 25 */
|
||||
#define ESP32_PERIPH_TG_T0_EDGE 58 /* INTR_STATUS_REG_1, bit 26 */
|
||||
#define ESP32_PERIPH_TG_T1_EDGE 59 /* INTR_STATUS_REG_1, bit 27 */
|
||||
#define ESP32_PERIPH_TG_WDT_EDGE 60 /* INTR_STATUS_REG_1, bit 28 */
|
||||
#define ESP32_PERIPH_TG_LACT_EDGE 61 /* INTR_STATUS_REG_1, bit 29 */
|
||||
|
||||
#define XTENSA_IRQ_TG1_T0_EDGE 65 /* INTR_STATUS_REG_1, bit 30 */
|
||||
#define XTENSA_IRQ_TG1_T1_EDGE 66 /* INTR_STATUS_REG_1, bit 31 */
|
||||
#define ESP32_PERIPH_TG1_T0_EDGE 62 /* INTR_STATUS_REG_1, bit 30 */
|
||||
#define ESP32_PERIPH_TG1_T1_EDGE 63 /* INTR_STATUS_REG_1, bit 31 */
|
||||
|
||||
/* PRO_INTR_STATUS_REG_2 / APP_INTR_STATUS_REG_2 */
|
||||
|
||||
#define XTENSA_IRQ_SREG2 67
|
||||
#define XTENSA_IRQ_TG1_WDT_EDGE 67 /* INTR_STATUS_REG_2, bit 0 */
|
||||
#define XTENSA_IRQ_TG1_LACT_EDGE 68 /* INTR_STATUS_REG_2, bit 1 */
|
||||
#define XTENSA_IRQ_MMU_IA 69 /* INTR_STATUS_REG_2, bit 2 */
|
||||
#define XTENSA_IRQ_MPU_IA 70 /* INTR_STATUS_REG_2, bit 3 */
|
||||
#define XTENSA_IRQ_CACHE_IA 71 /* INTR_STATUS_REG_2, bit 4 */
|
||||
#define ESP32_PERIPH_TG1_WDT_EDGE 64 /* INTR_STATUS_REG_2, bit 0 */
|
||||
#define ESP32_PERIPH_TG1_LACT_EDGE 65 /* INTR_STATUS_REG_2, bit 1 */
|
||||
#define ESP32_PERIPH_MMU_IA 66 /* INTR_STATUS_REG_2, bit 2 */
|
||||
#define ESP32_PERIPH_MPU_IA 67 /* INTR_STATUS_REG_2, bit 3 */
|
||||
#define ESP32_PERIPH_CACHE_IA 68 /* INTR_STATUS_REG_2, bit 4 */
|
||||
|
||||
/* Total number of peripherals */
|
||||
|
||||
#define NR_PERIPHERALS 69
|
||||
|
||||
/* Exceptions
|
||||
*
|
||||
* IRAM Offset Description
|
||||
* 0x0000 Windows
|
||||
* 0x0180 Level 2 interrupt
|
||||
* 0x01c0 Level 3 interrupt
|
||||
* 0x0200 Level 4 interrupt
|
||||
* 0x0240 Level 5 interrupt
|
||||
* 0x0280 Debug exception
|
||||
* 0x02c0 NMI exception
|
||||
* 0x0300 Kernel exception
|
||||
* 0x0340 User exception
|
||||
* 0x03c0 Double exception
|
||||
*
|
||||
* REVISIT: In more architectures supported by NuttX, exception errors
|
||||
* tie into the normal interrupt handling via special IRQ numbers. I
|
||||
* is still to be determined what will be done for the ESP32.
|
||||
*/
|
||||
|
||||
/* IRQ numbers for internal interrupts that are dispatched like peripheral
|
||||
* interrupts
|
||||
*/
|
||||
|
||||
#define XTENSA_IRQ_TIMER0 0 /* INTERRUPT, bit 6 */
|
||||
#define XTENSA_IRQ_TIMER1 1 /* INTERRUPT, bit 15 */
|
||||
#define XTENSA_IRQ_TIMER2 2 /* INTERRUPT, bit 16 */
|
||||
|
||||
#define XTENSA_IRQ_FIRSTPERIPH 3 /* First peripheral IRQ number */
|
||||
|
||||
/* IRQ numbers for peripheral interrupts coming throught the Interrupt
|
||||
* Matrix.
|
||||
*/
|
||||
|
||||
#define ESP32_IRQ2PERIPH(irq) ((irq)-XTENSA_IRQ_FIRSTPERIPH)
|
||||
|
||||
/* PRO_INTR_STATUS_REG_0 / APP_INTR_STATUS_REG_0 */
|
||||
|
||||
#define ESP32_IRQ_MAC (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_MAC)
|
||||
#define ESP32_IRQ_MAC_NMI (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_MAC_NMI)
|
||||
#define ESP32_IRQ_BB (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_BB)
|
||||
#define ESP32_IRQ_BB_MAC (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_BB_MAC)
|
||||
#define ESP32_IRQ_BT_BB (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_BT_BB)
|
||||
#define ESP32_IRQ_BT_BB_NMI (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_BT_BB_NMI)
|
||||
#define ESP32_IRQ_RWBT_IRQ (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RWBT_IRQ)
|
||||
#define ESP32_IRQ_RWBLE_IRQ (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RWBLE_IRQ)
|
||||
#define ESP32_IRQ_RWBT_NMI (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RWBT_NMI)
|
||||
#define ESP32_IRQ_RWBLE_NMI (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RWBLE_NMI)
|
||||
#define ESP32_IRQ_SLC0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SLC0)
|
||||
#define ESP32_IRQ_SLC1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SLC1)
|
||||
#define ESP32_IRQ_UHCI0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_UHCI0)
|
||||
#define ESP32_IRQ_UHCI1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_UHCI1)
|
||||
#define ESP32_IRQ_TG_T0_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_T0_LEVEL)
|
||||
#define ESP32_IRQ_TG_T1_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_T1_LEVEL)
|
||||
#define ESP32_IRQ_TG_WDT_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_WDT_LEVEL)
|
||||
#define ESP32_IRQ_TG_LACT_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_LACT_LEVEL)
|
||||
#define ESP32_IRQ_TG1_T0_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_T0_LEVEL)
|
||||
#define ESP32_IRQ_TG1_T1_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_T1_LEVEL)
|
||||
#define ESP32_IRQ_TG1_WDT_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_WDT_LEVEL)
|
||||
#define ESP32_IRQ_G1_LACT_LEVEL (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_G1_LACT_LEVEL)
|
||||
#define ESP32_IRQ_CPU_GPIO (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CPU_GPIO)
|
||||
#define ESP32_IRQ_CPU_NMI (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CPU_NMI)
|
||||
#define ESP32_IRQ_CPU_CPU0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CPU_CPU0)
|
||||
#define ESP32_IRQ_CPU_CPU1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CPU_CPU1)
|
||||
#define ESP32_IRQ_CPU_CPU2 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CPU_CPU2)
|
||||
#define ESP32_IRQ_CPU_CPU3 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CPU_CPU3)
|
||||
#define ESP32_IRQ_SPI0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI0)
|
||||
#define ESP32_IRQ_SPI1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI1
|
||||
#define ESP32_IRQ_SPI2 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI2)
|
||||
#define ESP32_IRQ_SPI3 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI3
|
||||
|
||||
#define ESP32_IRQ_SREG0 ESP32_IRQ_MAC
|
||||
#define ESP32_NIRQS_SREG0 32
|
||||
|
||||
/* PRO_INTR_STATUS_REG_1 / APP_INTR_STATUS_REG_1 */
|
||||
|
||||
#define ESP32_IRQ_I2S0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_I2S0)
|
||||
#define ESP32_IRQ_I2S1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_I2S1)
|
||||
#define ESP32_IRQ_UART (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_UART)
|
||||
#define ESP32_IRQ_UART1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_UART1)
|
||||
#define ESP32_IRQ_UART2 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_UART2)
|
||||
#define ESP32_IRQ_SDIO_HOST (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SDIO_HOST)
|
||||
#define ESP32_IRQ_EMAC (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_EMAC)
|
||||
#define ESP32_IRQ_PWM0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_PWM0)
|
||||
#define ESP32_IRQ_PWM1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_PWM1)
|
||||
#define ESP32_IRQ_PWM2 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_PWM2)
|
||||
#define ESP32_IRQ_PWM3 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_PWM3)
|
||||
#define ESP32_IRQ_LEDC (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_LEDC)
|
||||
#define ESP32_IRQ_EFUSE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_EFUSE)
|
||||
#define ESP32_IRQ_CAN (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CAN)
|
||||
#define ESP32_IRQ_RTC_CORE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RTC_CORE)
|
||||
#define ESP32_IRQ_RMT (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RMT)
|
||||
#define ESP32_IRQ_PCNT (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_PCNT)
|
||||
#define ESP32_IRQ_I2C_EXT0 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_I2C_EXT0)
|
||||
#define ESP32_IRQ_I2C_EXT1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_I2C_EXT1)
|
||||
#define ESP32_IRQ_RSA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_RSA)
|
||||
#define ESP32_IRQ_SPI1_DMA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI1_DMA)
|
||||
#define ESP32_IRQ_SPI2_DMA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI2_DMA)
|
||||
#define ESP32_IRQ_SPI3_DMA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_SPI3_DMA)
|
||||
#define ESP32_IRQ_WDG (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_WDG)
|
||||
#define ESP32_IRQ_TIMER1 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TIMER1)
|
||||
#define ESP32_IRQ_TIMER2 (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TIMER2)
|
||||
#define ESP32_IRQ_TG_T0_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_T0_EDGE)
|
||||
#define ESP32_IRQ_TG_T1_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_T1_EDGE)
|
||||
#define ESP32_IRQ_TG_WDT_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_WDT_EDGE)
|
||||
#define ESP32_IRQ_TG_LACT_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG_LACT_EDGE)
|
||||
#define ESP32_IRQ_TG1_T0_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_T0_EDGE)
|
||||
#define ESP32_IRQ_TG1_T1_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_T1_EDGE)
|
||||
|
||||
#define ESP32_IRQ_SREG1 ESP32_IRQ_I2S0
|
||||
#define ESP32_NIRQS_SREG1 32
|
||||
|
||||
/* PRO_INTR_STATUS_REG_2 / APP_INTR_STATUS_REG_2 */
|
||||
|
||||
#define ESP32_IRQ_TG1_WDT_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_WDT_EDGE)
|
||||
#define ESP32_IRQ_TG1_LACT_EDGE (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_TG1_LACT_EDGE)
|
||||
#define ESP32_IRQ_MMU_IA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_MMU_IA)
|
||||
#define ESP32_IRQ_MPU_IA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_MPU_IA)
|
||||
#define ESP32_IRQ_CACHE_IA (XTENSA_IRQ_FIRSTPERIPH+ESP32_PERIPH_CACHE_IA)
|
||||
|
||||
#define ESP32_IRQ_SREG2 ESP32_IRQ_TG1_WDT_EDGE
|
||||
#define ESP32_NIRQS_SREG2 5
|
||||
|
||||
/* Total number of interrupts */
|
||||
|
||||
#define NR_IRQS 72
|
||||
#define NR_IRQS (ESP32_IRQ_CACHE_IA+1)
|
||||
|
||||
/* CPU Interrupts.
|
||||
*
|
||||
* Each of the two CPUs (PRO and APP) have 32 interrupts each, of which
|
||||
* 26 can be mapped to peripheral interrupts:
|
||||
*
|
||||
* Level triggered peripherals (21 total):
|
||||
* 0-5, 8-9, 12-13, 17-21, 23-27, 31
|
||||
* Edge triggered peripherals (4 total):
|
||||
* 10, 22, 28, 30
|
||||
* NMI (1 total):
|
||||
* 14
|
||||
*
|
||||
* CPU peripheral interrupts can be a assigned to a CPU interrupt using the
|
||||
* PRO_*_MAP_REG or APP_*_MAP_REG. There are a pair of these registers for
|
||||
* each peripheral source. Multiple peripheral interrupt sources can be
|
||||
* mapped to the same.
|
||||
*
|
||||
* The remaining, five, internal CPU interrupts are:
|
||||
*
|
||||
* 6 Timer0
|
||||
* 7 Software
|
||||
* 15 Timer1
|
||||
* 16 Timer2
|
||||
* 29 Software
|
||||
*
|
||||
* A peripheral interrupt can be disabled
|
||||
*/
|
||||
|
||||
#define ESP32_CPUINT_LEVELPERIPH_0 0
|
||||
#define ESP32_CPUINT_LEVELPERIPH_1 1
|
||||
#define ESP32_CPUINT_LEVELPERIPH_2 2
|
||||
#define ESP32_CPUINT_LEVELPERIPH_3 3
|
||||
#define ESP32_CPUINT_LEVELPERIPH_4 4
|
||||
#define ESP32_CPUINT_LEVELPERIPH_5 5
|
||||
#define ESP32_CPUINT_LEVELPERIPH_6 8
|
||||
#define ESP32_CPUINT_LEVELPERIPH_7 9
|
||||
#define ESP32_CPUINT_LEVELPERIPH_8 12
|
||||
#define ESP32_CPUINT_LEVELPERIPH_9 13
|
||||
#define ESP32_CPUINT_LEVELPERIPH_10 17
|
||||
#define ESP32_CPUINT_LEVELPERIPH_11 18
|
||||
#define ESP32_CPUINT_LEVELPERIPH_12 19
|
||||
#define ESP32_CPUINT_LEVELPERIPH_13 20
|
||||
#define ESP32_CPUINT_LEVELPERIPH_14 21
|
||||
#define ESP32_CPUINT_LEVELPERIPH_15 23
|
||||
#define ESP32_CPUINT_LEVELPERIPH_16 24
|
||||
#define ESP32_CPUINT_LEVELPERIPH_17 25
|
||||
#define ESP32_CPUINT_LEVELPERIPH_18 26
|
||||
#define ESP32_CPUINT_LEVELPERIPH_19 27
|
||||
#define ESP32_CPUINT_LEVELPERIPH_20 31
|
||||
#define ESP32_CPUINT_NLEVELPERIPHS 21
|
||||
|
||||
#define ESP32_CPUINT_EDGEPERIPH_0 10
|
||||
#define ESP32_CPUINT_EDGEPERIPH_1 22
|
||||
#define ESP32_CPUINT_EDGEPERIPH_2 28
|
||||
#define ESP32_CPUINT_EDGEPERIPH_3 30
|
||||
#define ESP32_CPUINT_NEDGEPERIPHS 4
|
||||
|
||||
#define ESP32_CPUINT_TIMER0 6
|
||||
#define ESP32_CPUINT_SOFTWARE0 7
|
||||
#define ESP32_CPUINT_TIMER1 15
|
||||
#define ESP32_CPUINT_TIMER2 16
|
||||
#define ESP32_CPUINT_SOFTWARE1 29
|
||||
#define ESP32_CPUINT_NINTERNAL 5
|
||||
|
||||
#define ESP32_CPUINT_MAX 31
|
||||
#define EPS32_CPUINT_PERIPHSET 0xdffe7f3f
|
||||
#define EPS32_CPUINT_INTERNALSET 0x200180c0
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
|
||||
@@ -156,13 +156,6 @@ extern volatile uint32_t *g_current_regs[1];
|
||||
|
||||
#endif
|
||||
|
||||
/* This is the beginning of heap as provided from *_head.S. This is the
|
||||
* first address in DRAM after the loaded program+bss+idle stack. The end
|
||||
* of the heap is CONFIG_RAM_END
|
||||
*/
|
||||
|
||||
extern uint32_t g_idle_topstack;
|
||||
|
||||
/* Address of the saved user stack pointer */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
@@ -243,6 +236,8 @@ void xtensa_dumpstate(void);
|
||||
|
||||
uint32_t *xtensa_int_decode(uint32_t *regs);
|
||||
uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs);
|
||||
uint32_t xtensa_enable_cpuint(uint32_t *shadow, uint32_t intmask);
|
||||
uint32_t xtensa_disable_cpuint(uint32_t *shadow, uint32_t intmask);
|
||||
|
||||
/* Software interrupt handler */
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/common/xtensa_cpuint.S
|
||||
*
|
||||
* Adapted from use in NuttX by:
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Derives from logic originally provided by Cadence Design Systems Inc.
|
||||
*
|
||||
* Copyright (c) 2006-2015 Cadence Design Systems Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.file "xtensa_cpuint.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
#include <xtensa/config/core.h>
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_enable_cpuint
|
||||
*
|
||||
* C Prototype:
|
||||
* uint32_t xtensa_enable_cpuint(uint32_t *shadow, unsigned int intmask)
|
||||
*
|
||||
* Description:
|
||||
* Enables a set of interrupts. Does not simply set INTENABLE directly,
|
||||
* but operates on a shadow copy of the CPU INTENABLE register then
|
||||
* writes that value to the hardware INTENABLE register. Can be called
|
||||
* from interrupt handlers.
|
||||
*
|
||||
* NOTE: It is possible only to enable interrupts on the current CPU
|
||||
* because there is an INTENABLE register implemented in each CPU.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
.global xtensa_enable_cpuint
|
||||
.type xtensa_enable_cpuint, @function
|
||||
.align 4
|
||||
|
||||
xtensa_enable_cpuint:
|
||||
|
||||
movi a4, 0
|
||||
xsr a4, INTENABLE /* Disables all interrupts */
|
||||
rsync
|
||||
|
||||
l32i a4, a2, 0 /* a4 = value of INTENABLE shadow */
|
||||
or a5, a4, a3 /* a5 = shadow | mask */
|
||||
s32i a5, a2, 0 /* shadow |= mask */
|
||||
|
||||
wsr a5, INTENABLE /* Set CPU INTENABLE to shadow */
|
||||
mov a3, a4 /* Return previous shadow content */
|
||||
ret
|
||||
|
||||
.size xtensa_enable_cpuint, . - xtensa_enable_cpuint
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_disable_cpuint
|
||||
*
|
||||
* C Prototype:
|
||||
* uint32_t xtensa_disable_cpuint(uint32_t *shadow, unsigned int intmask)
|
||||
*
|
||||
* Description:
|
||||
* Disables a set of interrupts. Does not simply set INTENABLE directly,
|
||||
* but operates on a shadow copy of the CPU INTENABLE register then
|
||||
* writes that value to the hardware INTENABLE register. Can be called
|
||||
* from interrupt handlers.
|
||||
*
|
||||
* NOTE: It is possible only to enable interrupts on the current CPU
|
||||
* because there is an INTENABLE register implemented in each CPU.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
.globa xtensa_disable_cpuint
|
||||
.type xtensa_disable_cpuint, @function
|
||||
.align 4
|
||||
|
||||
xtensa_disable_cpuint:
|
||||
|
||||
movi a4, 0
|
||||
xsr a4, INTENABLE /* Disables all interrupts */
|
||||
rsync
|
||||
|
||||
l32i a4, a2, 0 /* a4 = value of INTENABLE shadow */
|
||||
or a5, a4, a3 /* a5 = shadow | mask */
|
||||
xor a5, a5, a3 /* a5 = shadow & ~mask */
|
||||
s32i a5, a2, 0 /* shadow &= ~mask */
|
||||
|
||||
wsr a5, INTENABLE /* Set CPU INTENABLE to shadow */
|
||||
mov a3, a4 /* Return previous shadow content */
|
||||
ret
|
||||
|
||||
.size xtensa_disable_cpuint, . - xtensa_disable_cpuint
|
||||
|
||||
#endif /* XCHAL_HAVE_INTERRUPTS */
|
||||
@@ -44,14 +44,15 @@ CMN_ASRCS = xtensa_context.S xtensa_vectors.S xtensa_inthandlers.S
|
||||
CMN_ASRCS += xtensa_nmihandler.S
|
||||
|
||||
CMN_CSRCS = xtensa_assert.c xtensa_blocktask.c xtensa_copystate.c
|
||||
CMN_CSRCS += xtensa_createstack.c xtensa_exit.c xtensa_idle.c
|
||||
CMN_CSRCS += xtensa_initialize.c xtensa_initialstate.c
|
||||
CMN_CSRCS += xtensa_interruptcontext.c xtensa_irqdispatch.c xtensa_lowputs.c
|
||||
CMN_CSRCS += xtensa_mdelay.c xtensa_modifyreg8.c xtensa_modifyreg16.c
|
||||
CMN_CSRCS += xtensa_modifyreg32.c xtensa_puts.c xtensa_releasepending.c
|
||||
CMN_CSRCS += xtensa_releasestack.c xtensa_reprioritizertr.c
|
||||
CMN_CSRCS += xtensa_schedsigaction.c xtensa_sigdeliver.c xtensa_stackframe.c
|
||||
CMN_CSRCS += xtensa_udelay.c xtensa_unblocktask.c xtensa_usestack.c
|
||||
CMN_CSRCS += xtens_cpuint.c xtensa_createstack.c xtensa_exit.c
|
||||
CMN_CSRCS += xtensa_idle.c xtensa_initialize.c xtensa_initialstate.c
|
||||
CMN_CSRCS += xtensa_interruptcontext.c xtensa_irqdispatch.c
|
||||
CMN_CSRCS += xtensa_lowputs.c xtensa_mdelay.c xtensa_modifyreg8.c
|
||||
CMN_CSRCS += xtensa_modifyreg16.c xtensa_modifyreg32.c xtensa_puts.c
|
||||
CMN_CSRCS += xtensa_releasepending.c xtensa_releasestack.c
|
||||
CMN_CSRCS += xtensa_reprioritizertr.c xtensa_schedsigaction.c
|
||||
CMN_CSRCS += xtensa_sigdeliver.c xtensa_stackframe.c xtensa_udelay.c
|
||||
CMN_CSRCS += xtensa_unblocktask.c xtensa_usestack.c
|
||||
|
||||
# Configuration-dependent common XTENSA files
|
||||
|
||||
@@ -77,8 +78,8 @@ endif
|
||||
# Required ESP32 files (arch/xtensa/src/lx6)
|
||||
|
||||
CHIP_ASRCS =
|
||||
CHIP_CSRCS = esp32_allocateheap.c esp32_intdecode.c esp32_irq.c
|
||||
CHIP_CSRCS += esp32_region.c esp32_start.c esp32_timerisr.c
|
||||
CHIP_CSRCS = esp32_allocateheap.c esp32_cpuint.c esp32_intdecode.c
|
||||
CHIP_CSRCS += esp32_irq.c esp32_region.c esp32_start.c esp32_timerisr.c
|
||||
|
||||
# Configuration-dependent ESP32 files
|
||||
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_irq.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ESP32_INTSET(n) ((1 << (n)) - 1)
|
||||
#define ESP32_LEVEL_SET ESP32_INTSET(ESP32_CPUINT_NLEVELPERIPHS)
|
||||
#define ESP32_EDGE_SET ESP32_INTSET(ESP32_CPUINT_NEDGEPERIPHS)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* g_intenable[] is a shadow copy of the per-CPU INTENABLE register
|
||||
* content.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
static uint32_t *g_intenable[CONFIG_SMP_NCPUS];
|
||||
|
||||
#else
|
||||
|
||||
static uint32_t *g_intenable[1];
|
||||
|
||||
#endif
|
||||
|
||||
/* Bitsets for free, unallocated CPU interrupts */
|
||||
|
||||
status uint32_t g_level_ints = ESP32_LEVEL_SET;
|
||||
status uint32_t g_edge_ints = ESP32_EDGE_SET;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disable_irq
|
||||
*
|
||||
* Description:
|
||||
* Disable the CPU interrupt specified by 'cpuint'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_disable_irq(int cpuint)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
int cpu;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint <= ESP32_CPUINT_MAX);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu = up_cpu_index();
|
||||
(void)xtensa_disable_cpuint(&g_intenable[cpu], (1ul << cpuint))
|
||||
#else
|
||||
(void)xtensa_disable_cpuint(&g_intenable[0], (1ul << cpuint))
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enable_irq
|
||||
*
|
||||
* Description:
|
||||
* Ensable the CPU interrupt specified by 'cpuint'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_enable_irq(int cpuint)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
int cpu;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint <= ESP32_CPUINT_MAX);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu = up_cpu_index();
|
||||
(void)xtensa_enable_cpuint(&g_intenable[cpu], (1ul << cpuint))
|
||||
#else
|
||||
(void)xtensa_enable_cpuint(&g_intenable[0], (1ul << cpuint))
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_levelint
|
||||
*
|
||||
* Description:
|
||||
* Allocate a level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated level-sensitive, CPU interrupt numbr is
|
||||
* returned. A negated errno is returned on failure. The only possible
|
||||
* failure is that all level-sensitive CPU interrupts have already been
|
||||
* allocated.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_levelint(void)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
/* Check if there are any level CPU interrupts available */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if ((g_level_ints & ESP32_LEVEL_SET) != 0)
|
||||
{
|
||||
/* Search for an unallocated CPU interrupt number in g_level_ints. */
|
||||
|
||||
for (cpuint = 0; cpuint < ESP32_CPUINT_NLEVELPERIPHS; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((g_level_ints & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
g_level_ints &= ~mask;
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_levelint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_levelint(int cpuint)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint < ESP32_CPUINT_NLEVELPERIPHS);
|
||||
|
||||
/* Mark the CPU interrupt as available */
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
flags = enter_critical_section();
|
||||
DEBUGASSERT((g_level_ints & mask) == 0);
|
||||
g_level_ints |= mask;
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_edgeint
|
||||
*
|
||||
* Description:
|
||||
* Allocate an edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated edge-sensitive, CPU interrupt numbr is
|
||||
* returned. A negated errno is returned on failure. The only possible
|
||||
* failure is that all edge-sensitive CPU interrupts have already been
|
||||
* allocated.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_edgeint(void)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
/* Check if there are any level CPU interrupts available */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if ((g_edge_ints & ESP32_EDGE_SET) != 0)
|
||||
{
|
||||
/* Search for an unallocated CPU interrupt number in g_edge_ints. */
|
||||
|
||||
for (cpuint = 0; cpuint < ESP32_CPUINT_NEDGEPERIPHS; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((g_edge_ints & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
g_edge_ints &= ~mask;
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_edgeint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_edgeint(int cpuint)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint < ESP32_CPUINT_NEDGEPERIPHS);
|
||||
|
||||
/* Mark the CPU interrupt as available */
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
flags = enter_critical_section();
|
||||
DEBUGASSERT((g_edge_ints & mask) == 0);
|
||||
g_edge_ints |= mask;
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_cpuint.h
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_CPUINT_H
|
||||
#define __ARCH_XTENSA_SRC_ESP32_ESP32_CPUINT_H 1
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_levelint
|
||||
*
|
||||
* Description:
|
||||
* Allocate a level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated level-sensitive, CPU interrupt numbr is
|
||||
* returned. A negated errno is returned on failure. The only possible
|
||||
* failure is that all level-sensitive CPU interrupts have already been
|
||||
* allocated.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_levelint(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_levelint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_levelint(int cpuint);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_edgeint
|
||||
*
|
||||
* Description:
|
||||
* Allocate an edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated edge-sensitive, CPU interrupt numbr is
|
||||
* returned. A negated errno is returned on failure. The only possible
|
||||
* failure is that all edge-sensitive CPU interrupts have already been
|
||||
* allocated.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_edgeint(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_edgeint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated edge CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_edgeint(int cpuint);
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_CPUINT_H */
|
||||
@@ -83,6 +83,20 @@ static inline void xtensa_registerdump(FAR struct tcb_s *tcb)
|
||||
# define xtensa_registerdump(tcb)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_disable_all
|
||||
****************************************************************************/
|
||||
|
||||
static inline void xtensa_disable_all(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a2, 0\n"
|
||||
"xsr a2, INTENABLE\n"
|
||||
: : : "a2"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -127,6 +141,13 @@ int xtensa_start_handler(int irq, FAR void *context)
|
||||
|
||||
esp32_region_protection();
|
||||
|
||||
/* Disable all PRO CPU interrupts */
|
||||
|
||||
xtensa_disable_all();
|
||||
|
||||
/* Disable peripheral sources from all PRO CPU interrupt */
|
||||
#warning Missing logic
|
||||
|
||||
/* Dump registers so that we can see what is going to happen on return */
|
||||
|
||||
xtensa_registerdump(tcb);
|
||||
|
||||
@@ -44,6 +44,24 @@
|
||||
#include "chip/esp32_dport.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const uint8_t g_baseirq[3] =
|
||||
{
|
||||
ESP32_IRQ_SREG0,
|
||||
ESP32_IRQ_SREG1,
|
||||
ESP32_IRQ_SREG2
|
||||
};
|
||||
|
||||
static const uint8_t g_nirqs[3] =
|
||||
{
|
||||
ESP32_NIRQS_SREG0,
|
||||
ESP32_NIRQS_SREG1,
|
||||
ESP32_NIRQS_SREG2
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -94,19 +112,23 @@ uint32_t *xtensa_int_decode(uint32_t *regs)
|
||||
* registers.
|
||||
*/
|
||||
|
||||
for (regndx = 0, baseirq = XTENSA_IRQ_SREG0;
|
||||
regndx < 3;
|
||||
regndx++, baseirq += 32, regaddr += sizeof(uint32_t))
|
||||
for (regndx = 0; regndx < 3; regndx++)
|
||||
{
|
||||
/* Fetch the next register status register */
|
||||
|
||||
regval = getreg32(regaddr);
|
||||
regval = getreg32(regaddr);
|
||||
regaddr += sizeof(uint32_t);
|
||||
|
||||
/* Set up the search */
|
||||
|
||||
baseirq = g_baseirq[regndx];
|
||||
nirqs = g_nirqs[regndx]
|
||||
|
||||
/* Decode and dispatch each pending bit in the interrupt status
|
||||
* register.
|
||||
*/
|
||||
|
||||
for (bit = 0; regval != 0 && bit < 32; bit++)
|
||||
for (bit = 0; regval != 0 && bit < nirqs; bit++)
|
||||
{
|
||||
/* Check if this interrupt is pending */
|
||||
|
||||
|
||||
@@ -48,10 +48,6 @@
|
||||
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@@ -62,8 +58,19 @@
|
||||
* CURRENT_REGS for portability.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* For the case of architectures with multiple CPUs, then there must be one
|
||||
* such value for each processor that can receive an interrupt.
|
||||
*/
|
||||
|
||||
volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS];
|
||||
|
||||
#else
|
||||
|
||||
volatile uint32_t *g_current_regs[1];
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -89,6 +96,20 @@ static void esp32_irq_dump(const char *msg, int irq)
|
||||
# define esp32_irq_dump(msg, irq)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: xtensa_disable_all
|
||||
****************************************************************************/
|
||||
|
||||
static inline void xtensa_disable_all(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a2, 0\n"
|
||||
"xsr a2, INTENABLE\n"
|
||||
: : : "a2"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -99,7 +120,11 @@ static void esp32_irq_dump(const char *msg, int irq)
|
||||
|
||||
void xtensa_irq_initialize(void)
|
||||
{
|
||||
/* Disable all interrupts */
|
||||
/* Disable all PRO CPU interrupts */
|
||||
|
||||
xtensa_disable_all();
|
||||
|
||||
/* Disable peripheral sources from all PRO CPU interrupt */
|
||||
#warning Missing logic
|
||||
|
||||
#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
@@ -111,72 +136,14 @@ void xtensa_irq_initialize(void)
|
||||
/* Set all interrupts (and exceptions) to the default priority */
|
||||
#warning Missing logic
|
||||
|
||||
/* Attach all other processor exceptions (except reset and sys tick) */
|
||||
/* Attach all processor exceptions */
|
||||
#warning Missing logic
|
||||
|
||||
esp32_irq_dump("initial", NR_IRQS);
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
up_irq_enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disable_irq
|
||||
*
|
||||
* Description:
|
||||
* Disable the IRQ specified by 'irq'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_disable_irq(int irq)
|
||||
{
|
||||
#warning Missing logic
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enable_irq
|
||||
*
|
||||
* Description:
|
||||
* Enable the IRQ specified by 'irq'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_enable_irq(int irq)
|
||||
{
|
||||
#warning Missing logic
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ack_irq
|
||||
*
|
||||
* Description:
|
||||
* Acknowledge the IRQ
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_ack_irq(int irq)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_prioritize_irq
|
||||
*
|
||||
* Description:
|
||||
* Set the priority of an IRQ.
|
||||
*
|
||||
* Since this API is not supported on all architectures, it should be
|
||||
* avoided in common implementations where possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_IRQPRIO
|
||||
int up_prioritize_irq(int irq, int priority)
|
||||
{
|
||||
#warning Missing logic
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -51,6 +51,14 @@
|
||||
#include "xtensa_timer.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if XT_TIMER_INTEN != ESP32_CPUINT_TIMER0
|
||||
# error Mismatch in irq.h and xtensa_timer.h
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private data
|
||||
****************************************************************************/
|
||||
@@ -62,8 +70,7 @@ static uint32_t g_tick_divisor;
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: xtensa_getcount, xtensa_getcompare, xtensa_setcompare, and
|
||||
* xtensa_enable_timer
|
||||
* Function: xtensa_getcount, xtensa_getcompare, and xtensa_setcompare
|
||||
*
|
||||
* Description:
|
||||
* Lower level operations on Xtensa special registers.
|
||||
@@ -108,22 +115,6 @@ static inline void xtensa_setcompare(uint32_t compare)
|
||||
);
|
||||
}
|
||||
|
||||
/* Enable the timer interrupt. NOTE: This is non-atomic but safe in this
|
||||
* context because this occurs early in the initialization sequence.
|
||||
*/
|
||||
|
||||
static inline void xtensa_enable_timer(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a3, %0\n"
|
||||
"rsr a2, INTENABLE\n"
|
||||
"or a2, a2, a3\n"
|
||||
"wsr a2, INTENABLE\n"
|
||||
: : "I"(XT_TIMER_INTEN) : "a2", "a3"
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: esp32_timerisr
|
||||
*
|
||||
@@ -212,9 +203,7 @@ void xtensa_timer_initialize(void)
|
||||
|
||||
(void)irq_attach(XTENSA_IRQ_TIMER0, (xcpt_t)esp32_timerisr);
|
||||
|
||||
/* Enable the timer interrupt at the device level. NOTE: It is un-necessary
|
||||
* to call up_enable_irq() for timers.
|
||||
*/
|
||||
/* Enable the timer 0 CPU interrupt. */
|
||||
|
||||
xtensa_enable_timer();
|
||||
up_enable_irq(ESP32_CPUINT_TIMER0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user