esp_hal/interrupt/
software.rs
1#![doc = crate::before_snippet!()]
14use crate::interrupt::{InterruptConfigurable, InterruptHandler};
52
53#[non_exhaustive]
55pub struct SoftwareInterrupt<const NUM: u8>;
56
57impl<const NUM: u8> SoftwareInterrupt<NUM> {
58 #[instability::unstable]
60 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
61 let interrupt = match NUM {
62 0 => crate::peripherals::Interrupt::FROM_CPU_INTR0,
63 1 => crate::peripherals::Interrupt::FROM_CPU_INTR1,
64 2 => crate::peripherals::Interrupt::FROM_CPU_INTR2,
65 3 => crate::peripherals::Interrupt::FROM_CPU_INTR3,
66 _ => unreachable!(),
67 };
68
69 for core in crate::system::Cpu::other() {
70 crate::interrupt::disable(core, interrupt);
71 }
72 unsafe { crate::interrupt::bind_interrupt(interrupt, handler.handler()) };
73 unwrap!(crate::interrupt::enable(interrupt, handler.priority()));
74 }
75
76 pub fn raise(&self) {
78 cfg_if::cfg_if! {
79 if #[cfg(any(esp32c6, esp32h2))] {
80 let system = crate::peripherals::INTPRI::regs();
81 } else {
82 let system = crate::peripherals::SYSTEM::regs();
83 }
84 }
85
86 match NUM {
87 0 => system
88 .cpu_intr_from_cpu_0()
89 .write(|w| w.cpu_intr_from_cpu_0().set_bit()),
90 1 => system
91 .cpu_intr_from_cpu_1()
92 .write(|w| w.cpu_intr_from_cpu_1().set_bit()),
93 2 => system
94 .cpu_intr_from_cpu_2()
95 .write(|w| w.cpu_intr_from_cpu_2().set_bit()),
96 3 => system
97 .cpu_intr_from_cpu_3()
98 .write(|w| w.cpu_intr_from_cpu_3().set_bit()),
99 _ => unreachable!(),
100 };
101 }
102
103 pub fn reset(&self) {
105 cfg_if::cfg_if! {
106 if #[cfg(any(esp32c6, esp32h2))] {
107 let system = crate::peripherals::INTPRI::regs();
108 } else {
109 let system = crate::peripherals::SYSTEM::regs();
110 }
111 }
112
113 match NUM {
114 0 => system
115 .cpu_intr_from_cpu_0()
116 .write(|w| w.cpu_intr_from_cpu_0().clear_bit()),
117 1 => system
118 .cpu_intr_from_cpu_1()
119 .write(|w| w.cpu_intr_from_cpu_1().clear_bit()),
120 2 => system
121 .cpu_intr_from_cpu_2()
122 .write(|w| w.cpu_intr_from_cpu_2().clear_bit()),
123 3 => system
124 .cpu_intr_from_cpu_3()
125 .write(|w| w.cpu_intr_from_cpu_3().clear_bit()),
126 _ => unreachable!(),
127 };
128 }
129
130 #[inline]
137 pub unsafe fn steal() -> Self {
138 Self
139 }
140}
141
142impl<const NUM: u8> crate::peripheral::Peripheral for SoftwareInterrupt<NUM> {
143 type P = SoftwareInterrupt<NUM>;
144
145 #[inline]
146 unsafe fn clone_unchecked(&self) -> Self::P {
147 Self::steal()
148 }
149}
150
151impl<const NUM: u8> crate::private::Sealed for SoftwareInterrupt<NUM> {}
152
153impl<const NUM: u8> InterruptConfigurable for SoftwareInterrupt<NUM> {
154 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
155 SoftwareInterrupt::set_interrupt_handler(self, handler);
156 }
157}
158
159#[cfg_attr(
165 multi_core,
166 doc = r#"
167
168Please note: Software interrupt 3 is reserved
169for inter-processor communication when using
170`esp-hal-embassy`."#
171)]
172#[non_exhaustive]
173pub struct SoftwareInterruptControl {
174 pub software_interrupt0: SoftwareInterrupt<0>,
176 pub software_interrupt1: SoftwareInterrupt<1>,
178 pub software_interrupt2: SoftwareInterrupt<2>,
180 #[cfg(not(all(feature = "__esp_hal_embassy", multi_core)))]
181 pub software_interrupt3: SoftwareInterrupt<3>,
184}
185
186impl SoftwareInterruptControl {
187 pub fn new(_peripheral: crate::peripherals::SW_INTERRUPT) -> Self {
189 SoftwareInterruptControl {
190 software_interrupt0: SoftwareInterrupt {},
191 software_interrupt1: SoftwareInterrupt {},
192 software_interrupt2: SoftwareInterrupt {},
193 #[cfg(not(all(feature = "__esp_hal_embassy", multi_core)))]
194 software_interrupt3: SoftwareInterrupt {},
195 }
196 }
197}