-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/ulp_riscv_interrupt_handling' into 'master'
feat(ulp-riscv): Added interrupt handling for ULP RISC-V Closes IDFGH-9866 and IDF-1713 See merge request espressif/esp-idf!27802
- Loading branch information
Showing
21 changed files
with
854 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
#include <stdint.h> | ||
#include "esp_err.h" | ||
#include "riscv/interrupt.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
/* ULP RISC-V Interrupt sources */ | ||
typedef enum { | ||
ULP_RISCV_SW_INTR_SOURCE = 0, /**< Interrupt triggered by SW */ | ||
ULP_RISCV_RTCIO0_INTR_SOURCE, /**< Interrupt triggered by RTCIO 0 */ | ||
ULP_RISCV_RTCIO1_INTR_SOURCE, /**< Interrupt triggered by RTCIO 1 */ | ||
ULP_RISCV_RTCIO2_INTR_SOURCE, /**< Interrupt triggered by RTCIO 2 */ | ||
ULP_RISCV_RTCIO3_INTR_SOURCE, /**< Interrupt triggered by RTCIO 3 */ | ||
ULP_RISCV_RTCIO4_INTR_SOURCE, /**< Interrupt triggered by RTCIO 4 */ | ||
ULP_RISCV_RTCIO5_INTR_SOURCE, /**< Interrupt triggered by RTCIO 5 */ | ||
ULP_RISCV_RTCIO6_INTR_SOURCE, /**< Interrupt triggered by RTCIO 6 */ | ||
ULP_RISCV_RTCIO7_INTR_SOURCE, /**< Interrupt triggered by RTCIO 7 */ | ||
ULP_RISCV_RTCIO8_INTR_SOURCE, /**< Interrupt triggered by RTCIO 8 */ | ||
ULP_RISCV_RTCIO9_INTR_SOURCE, /**< Interrupt triggered by RTCIO 9 */ | ||
ULP_RISCV_RTCIO10_INTR_SOURCE, /**< Interrupt triggered by RTCIO 10 */ | ||
ULP_RISCV_RTCIO11_INTR_SOURCE, /**< Interrupt triggered by RTCIO 11 */ | ||
ULP_RISCV_RTCIO12_INTR_SOURCE, /**< Interrupt triggered by RTCIO 12 */ | ||
ULP_RISCV_RTCIO13_INTR_SOURCE, /**< Interrupt triggered by RTCIO 13 */ | ||
ULP_RISCV_RTCIO14_INTR_SOURCE, /**< Interrupt triggered by RTCIO 14 */ | ||
ULP_RISCV_RTCIO15_INTR_SOURCE, /**< Interrupt triggered by RTCIO 15 */ | ||
ULP_RISCV_RTCIO16_INTR_SOURCE, /**< Interrupt triggered by RTCIO 16 */ | ||
ULP_RISCV_RTCIO17_INTR_SOURCE, /**< Interrupt triggered by RTCIO 17 */ | ||
ULP_RISCV_RTCIO18_INTR_SOURCE, /**< Interrupt triggered by RTCIO 18 */ | ||
ULP_RISCV_RTCIO19_INTR_SOURCE, /**< Interrupt triggered by RTCIO 19 */ | ||
ULP_RISCV_RTCIO20_INTR_SOURCE, /**< Interrupt triggered by RTCIO 20 */ | ||
ULP_RISCV_RTCIO21_INTR_SOURCE, /**< Interrupt triggered by RTCIO 21 */ | ||
ULP_RISCV_MAX_INTR_SOURCE, /**< Total number of ULP RISC-V interrupt sources */ | ||
} ulp_riscv_interrupt_source_t; | ||
|
||
/** | ||
* @brief Allocate interrupt handler for a ULP RISC-V interrupt source | ||
* | ||
* @param source ULP RISC-V interrupt source | ||
* @param handler Interrupt handler | ||
* @param arg Interrupt handler argument | ||
* | ||
* @return esp_err_t ESP_OK when successful | ||
*/ | ||
esp_err_t ulp_riscv_intr_alloc(ulp_riscv_interrupt_source_t source, intr_handler_t handler, void *arg); | ||
|
||
/** | ||
* @brief Free ULP RISC-V interrupt handler | ||
* | ||
* @param source ULP RISC-V interrupt source | ||
* | ||
* @return esp_err_t ESP_OK when successful | ||
*/ | ||
esp_err_t ulp_riscv_intr_free(ulp_riscv_interrupt_source_t source); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
98 changes: 98 additions & 0 deletions
98
components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt_ops.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2015-2021 Claire Xenia Wolf <[email protected]> | ||
* SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* This header file defines custom instructions for interrupt handling on the | ||
* ULP RISC-V. The architecture of the processor and therefore, the interrupt | ||
* handling is based on the PicoRV32 CPU. Details about the operations are | ||
* available at https://github.com/YosysHQ/picorv32#custom-instructions-for-irq-handling | ||
*/ | ||
|
||
/* Define encoding for all general purpose RISC-V registers */ | ||
#define regnum_zero 0 | ||
#define regnum_ra 1 | ||
#define regnum_sp 2 | ||
#define regnum_gp 3 | ||
#define regnum_tp 4 | ||
#define regnum_t0 5 | ||
#define regnum_t1 6 | ||
#define regnum_t2 7 | ||
#define regnum_s0 8 | ||
#define regnum_s1 9 | ||
#define regnum_a0 10 | ||
#define regnum_a1 11 | ||
#define regnum_a2 12 | ||
#define regnum_a3 13 | ||
#define regnum_a4 14 | ||
#define regnum_a5 15 | ||
#define regnum_a6 16 | ||
#define regnum_a7 17 | ||
#define regnum_s2 18 | ||
#define regnum_s3 19 | ||
#define regnum_s4 20 | ||
#define regnum_s5 21 | ||
#define regnum_s6 22 | ||
#define regnum_s7 23 | ||
#define regnum_s8 24 | ||
#define regnum_s9 25 | ||
#define regnum_s10 26 | ||
#define regnum_s11 27 | ||
#define regnum_t3 28 | ||
#define regnum_t4 29 | ||
#define regnum_t5 30 | ||
#define regnum_t6 31 | ||
|
||
/* Define encoding for special interrupt handling registers, viz., q0, q1, q2 and q3 */ | ||
#define regnum_q0 0 | ||
#define regnum_q1 1 | ||
#define regnum_q2 2 | ||
#define regnum_q3 3 | ||
|
||
/* All custom interrupt handling instructions follow the standard R-type instruction format from RISC-V ISA | ||
* with the same opcode of custom0 (0001011). | ||
*/ | ||
#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \ | ||
.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0)) | ||
|
||
/** | ||
* Instruction: getq rd, qs | ||
* Description: This instruction copies the value of Qx into a general purpose register rd | ||
*/ | ||
#define getq_insn(_rd, _qs) \ | ||
r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011) | ||
|
||
/** | ||
* Instruction: setq qd, rs | ||
* Description: This instruction copies the value of general purpose register rs to Qx | ||
*/ | ||
#define setq_insn(_qd, _rs) \ | ||
r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011) | ||
|
||
/** | ||
* Instruction: retirq | ||
* Description: This instruction copies the value of Q0 to CPU PC, and renables interrupts | ||
*/ | ||
#define retirq_insn() \ | ||
r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011) | ||
|
||
/** | ||
* Instruction: maskirq rd, rs | ||
* Description: This instruction copies the value of the register IRQ Mask to the register rd, and copies the value | ||
* of register rs to to IRQ mask. | ||
*/ | ||
#define maskirq_insn(_rd, _rs) \ | ||
r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011) | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,26 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD | ||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
.section .text.vectors | ||
.global irq_vector | ||
.global reset_vector | ||
|
||
/* The reset vector, jumps to startup code */ | ||
reset_vector: | ||
j __start | ||
#include "ulp_riscv_interrupt_ops.h" | ||
|
||
/* Interrupt handler */ | ||
.balign 16 | ||
irq_vector: | ||
ret | ||
|
||
.section .text | ||
.section .text | ||
.global __start | ||
|
||
.type __start, %function | ||
__start: | ||
/* setup the stack pointer */ | ||
la sp, __stack_top | ||
call ulp_riscv_rescue_from_monitor | ||
call main | ||
call ulp_riscv_halt | ||
/* setup the stack pointer */ | ||
la sp, __stack_top | ||
|
||
/* Enable interrupts globally */ | ||
maskirq_insn(zero, zero) | ||
|
||
/* Start ULP user code */ | ||
call ulp_riscv_rescue_from_monitor | ||
call main | ||
call ulp_riscv_halt | ||
loop: | ||
j loop | ||
j loop | ||
.size __start, .-__start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include "ulp_riscv_gpio.h" | ||
#include "include/ulp_riscv_gpio.h" | ||
|
||
esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_type_t intr_type, intr_handler_t handler, void *arg) | ||
{ | ||
if (gpio_num < 0 || gpio_num >= GPIO_NUM_MAX) { | ||
return ESP_ERR_INVALID_ARG; | ||
} | ||
|
||
if (intr_type < 0 || intr_type >= ULP_RISCV_GPIO_INTR_MAX) { | ||
return ESP_ERR_INVALID_ARG; | ||
} | ||
|
||
if (!handler) { | ||
return ESP_ERR_INVALID_ARG; | ||
} | ||
|
||
/* Set the interrupt type */ | ||
REG_SET_FIELD(RTC_GPIO_PIN0_REG + 4*gpio_num, RTC_GPIO_PIN0_INT_TYPE, intr_type); | ||
|
||
/* Set the interrupt handler */ | ||
return ulp_riscv_intr_alloc(ULP_RISCV_RTCIO0_INTR_SOURCE + gpio_num, handler, arg); | ||
} | ||
|
||
esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num) | ||
{ | ||
return ulp_riscv_intr_free(ULP_RISCV_RTCIO0_INTR_SOURCE + gpio_num); | ||
} |
Oops, something went wrong.