ESP32-C6 Technical Reference Manual possible errors regarding interrupt handling
Posted: Fri Aug 14, 2026 7:26 am
Hello,
I am trying to program a ESP32-C6 DevKitC-1 equipped with ESP32C6-WROOM-1 which has ESP32-C6 SoC.
After developing some applications with ESP-IDF, I decided to learn more about the core of SoC, hence tried to write some bare metal code reading through ESP32-C6 Technical Reference Manual.
However, I quickly ran into problem handling 28 external interrupts connected to CPU via INTMTX controller.
On Section 1.6.2, (1.6 Interrupt Controller -> 1.6.2 Functional Description)
Unfortunately, there seems to be several things wrong with the Interrupt Priority Registers and general mechanism of INTPRI.
1. INTPRI_CORE0_CPU_INT_ENABLE_REG doesn't actually seem to do anything. ESP-IDF hal function interrupt_plic_ll_get_unmask reads from PLIC_MXINT_ENABLE_REG, which end up being defined as 0x20001000, which resides on CPU Subsystem register memory region, neither INTMTX nor INTPRI peripheral register memory region. esprv_intc_int_enable calls bootrom function on address 0x40000720, which in turn does write on 0x20001000. I also verified that interrupt works when the bit index is set on 0x20001000 regardless of value set on INTPRI_CORE0_CPU_INT_ENABLE_REG.
2. Same for all other INTPRI_* registers, bootrom functions access registers mapped on 0x20001000 region.
3. INTPRI_DATE_REG seems to be reading different value from what's written on the document. It reads 0x02202280 instead of 0x02201090 specified on the document.
Any clarification about the said behaviours would be greatly appreciated.
I am trying to program a ESP32-C6 DevKitC-1 equipped with ESP32C6-WROOM-1 which has ESP32-C6 SoC.
After developing some applications with ESP-IDF, I decided to learn more about the core of SoC, hence tried to write some bare metal code reading through ESP32-C6 Technical Reference Manual.
However, I quickly ran into problem handling 28 external interrupts connected to CPU via INTMTX controller.
On Section 1.6.2, (1.6 Interrupt Controller -> 1.6.2 Functional Description)
And Section 10.5.2 (10 Interrupt Matrix -> 10.5.2 Interrupt Priority Registers) provides descriptions for INTPRI_* registers, which have base address of 0x600C5000, found from Section 5.3.5 (Modules/Peripherals Address Mapping)....
2. Enable State (0-1):
• Determines if an interrupt is enabled to be captured and serviced by the CPU.
• Programmed by writing the corresponding bit in INTPRI_CORE0_CPU_INT_ENABLE_REG.
• Local CLINT interrupts have the corresponding bits reserved in the memory mapped registers thus
they are always enabled at the INTC level.
• An M mode interrupt (external or local) further needs to be unmasked at core level by setting the
corresponding bit in mie CSR.
• A U mode interrupt (external or local) further needs to be unmasked at core level by setting the
corresponding bits in uie CSR.
...
Unfortunately, there seems to be several things wrong with the Interrupt Priority Registers and general mechanism of INTPRI.
1. INTPRI_CORE0_CPU_INT_ENABLE_REG doesn't actually seem to do anything. ESP-IDF hal function interrupt_plic_ll_get_unmask reads from PLIC_MXINT_ENABLE_REG, which end up being defined as 0x20001000, which resides on CPU Subsystem register memory region, neither INTMTX nor INTPRI peripheral register memory region. esprv_intc_int_enable calls bootrom function on address 0x40000720, which in turn does write on 0x20001000. I also verified that interrupt works when the bit index is set on 0x20001000 regardless of value set on INTPRI_CORE0_CPU_INT_ENABLE_REG.
2. Same for all other INTPRI_* registers, bootrom functions access registers mapped on 0x20001000 region.
3. INTPRI_DATE_REG seems to be reading different value from what's written on the document. It reads 0x02202280 instead of 0x02201090 specified on the document.
Any clarification about the said behaviours would be greatly appreciated.
- Documentation Version: ESP32-C6 Technical Reference Manual v1.2
- mvendorid: 0x612
- marchid: 0x80000002
- mimpid: 0x2