esp_hal/interrupt/
software.rs1#![doc = crate::before_snippet!()]
14use core::marker::PhantomData;
52
53use crate::interrupt::{InterruptConfigurable, InterruptHandler};
54
55#[non_exhaustive]
57pub struct SoftwareInterrupt<'d, const NUM: u8> {
58 _lifetime: PhantomData<&'d mut ()>,
59}
60
61impl<const NUM: u8> SoftwareInterrupt<'_, NUM> {
62 #[inline]
69 pub unsafe fn steal() -> Self {
70 Self {
71 _lifetime: PhantomData,
72 }
73 }
74
75 pub fn reborrow(&mut self) -> SoftwareInterrupt<'_, NUM> {
80 unsafe { SoftwareInterrupt::steal() }
81 }
82
83 #[instability::unstable]
85 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
86 let interrupt = match NUM {
87 0 => crate::peripherals::Interrupt::FROM_CPU_INTR0,
88 1 => crate::peripherals::Interrupt::FROM_CPU_INTR1,
89 2 => crate::peripherals::Interrupt::FROM_CPU_INTR2,
90 3 => crate::peripherals::Interrupt::FROM_CPU_INTR3,
91 _ => unreachable!(),
92 };
93
94 for core in crate::system::Cpu::other() {
95 crate::interrupt::disable(core, interrupt);
96 }
97 unsafe { crate::interrupt::bind_interrupt(interrupt, handler.handler()) };
98 unwrap!(crate::interrupt::enable(interrupt, handler.priority()));
99 }
100
101 pub fn raise(&self) {
103 cfg_if::cfg_if! {
104 if #[cfg(any(esp32c6, esp32h2))] {
105 let system = crate::peripherals::INTPRI::regs();
106 } else {
107 let system = crate::peripherals::SYSTEM::regs();
108 }
109 }
110
111 match NUM {
112 0 => system
113 .cpu_intr_from_cpu_0()
114 .write(|w| w.cpu_intr_from_cpu_0().set_bit()),
115 1 => system
116 .cpu_intr_from_cpu_1()
117 .write(|w| w.cpu_intr_from_cpu_1().set_bit()),
118 2 => system
119 .cpu_intr_from_cpu_2()
120 .write(|w| w.cpu_intr_from_cpu_2().set_bit()),
121 3 => system
122 .cpu_intr_from_cpu_3()
123 .write(|w| w.cpu_intr_from_cpu_3().set_bit()),
124 _ => unreachable!(),
125 };
126 }
127
128 pub fn reset(&self) {
130 cfg_if::cfg_if! {
131 if #[cfg(any(esp32c6, esp32h2))] {
132 let system = crate::peripherals::INTPRI::regs();
133 } else {
134 let system = crate::peripherals::SYSTEM::regs();
135 }
136 }
137
138 match NUM {
139 0 => system
140 .cpu_intr_from_cpu_0()
141 .write(|w| w.cpu_intr_from_cpu_0().clear_bit()),
142 1 => system
143 .cpu_intr_from_cpu_1()
144 .write(|w| w.cpu_intr_from_cpu_1().clear_bit()),
145 2 => system
146 .cpu_intr_from_cpu_2()
147 .write(|w| w.cpu_intr_from_cpu_2().clear_bit()),
148 3 => system
149 .cpu_intr_from_cpu_3()
150 .write(|w| w.cpu_intr_from_cpu_3().clear_bit()),
151 _ => unreachable!(),
152 };
153 }
154}
155
156impl<const NUM: u8> crate::private::Sealed for SoftwareInterrupt<'_, NUM> {}
157
158impl<const NUM: u8> InterruptConfigurable for SoftwareInterrupt<'_, NUM> {
159 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
160 SoftwareInterrupt::set_interrupt_handler(self, handler);
161 }
162}
163
164#[cfg_attr(
170 multi_core,
171 doc = r#"
172
173Please note: Software interrupt 3 is reserved
174for inter-processor communication when using
175`esp-hal-embassy`."#
176)]
177#[non_exhaustive]
178pub struct SoftwareInterruptControl<'d> {
179 pub software_interrupt0: SoftwareInterrupt<'d, 0>,
181 pub software_interrupt1: SoftwareInterrupt<'d, 1>,
183 #[cfg(not(all(feature = "__esp_wifi_builtin_scheduler", riscv)))]
186 pub software_interrupt2: SoftwareInterrupt<'d, 2>,
187 #[cfg(not(all(feature = "__esp_hal_embassy", multi_core)))]
188 pub software_interrupt3: SoftwareInterrupt<'d, 3>,
191}
192
193impl<'d> SoftwareInterruptControl<'d> {
194 pub fn new(_peripheral: crate::peripherals::SW_INTERRUPT<'d>) -> Self {
196 SoftwareInterruptControl {
197 software_interrupt0: SoftwareInterrupt {
198 _lifetime: PhantomData,
199 },
200 software_interrupt1: SoftwareInterrupt {
201 _lifetime: PhantomData,
202 },
203 #[cfg(not(all(feature = "__esp_wifi_builtin_scheduler", riscv)))]
204 software_interrupt2: SoftwareInterrupt {
205 _lifetime: PhantomData,
206 },
207 #[cfg(not(all(feature = "__esp_hal_embassy", multi_core)))]
208 software_interrupt3: SoftwareInterrupt {
209 _lifetime: PhantomData,
210 },
211 }
212 }
213}