aboutsummaryrefslogtreecommitdiff
path: root/src/interrupt.rs
diff options
context:
space:
mode:
authorMathisDerooNXP <[email protected]>2025-11-26 10:05:16 -0800
committerGitHub <[email protected]>2025-11-26 10:05:16 -0800
commitd12bc9785399991065e511efbea34f0138c7645e (patch)
tree47472365383c3a5ad5d4ab0495e655a3418477d9 /src/interrupt.rs
parent1efaaa4025120413ec17de90106244445208804a (diff)
Add GPIO interrupt support and embedded-hal-async trait implementation (#38)
* Add GPIO interrupt support and embedded-hal-async trait implementation Signed-off-by: Mathis Deroo <[email protected]> * Run cargo fmt * Improve GPIO driver interrupt mechanism and example - GPIO interrupt managed internally at the HAL level, - Renamed and cleaned gpio_interrupt example; now button_async.rs, - Use BitIter instead of simple for loop in the irq handler, - Fix comments and add "rt" wrappen to GPIO IRQ handler. Signed-off-by: Mathis Deroo <[email protected]> * Modify INTERRUPT_DETECTED (AtomicBool to AtomicU32) to work with pin number and not only port number interrupt Signed-off-by: Mathis Deroo <[email protected]> * add embedded_hal_async::digital::* traits Signed-off-by: Mathis Deroo <[email protected]> * Update irq_handler with BitIter loop Co-authored-by: Felipe Balbi <[email protected]> * Add suggested changes Signed-off-by: Mathis Deroo <[email protected]> * cargo fmt Signed-off-by: Felipe Balbi <[email protected]> * WIP: Modify Wakers from AtomicWaker to WaitMap, with pin number (per PORT) as key Signed-off-by: Mathis Deroo <[email protected]> * Tweak maitake-sync usage * Improve docs * refactor a bit * Move all of the async+interrupt stuff into a module * Remove defmt debug traces Signed-off-by: Mathis Deroo <[email protected]> * cargo vet * Move e-hal-async impls into the gated block * "rt", begone! --------- Signed-off-by: Mathis Deroo <[email protected]> Signed-off-by: Felipe Balbi <[email protected]> Co-authored-by: Felipe Balbi <[email protected]> Co-authored-by: Felipe Balbi <[email protected]> Co-authored-by: Felipe Balbi <[email protected]> Co-authored-by: James Munns <[email protected]>
Diffstat (limited to 'src/interrupt.rs')
-rw-r--r--src/interrupt.rs193
1 files changed, 192 insertions, 1 deletions
diff --git a/src/interrupt.rs b/src/interrupt.rs
index f2f1cccac..0490e3a66 100644
--- a/src/interrupt.rs
+++ b/src/interrupt.rs
@@ -8,7 +8,8 @@
8 8
9mod generated { 9mod generated {
10 embassy_hal_internal::interrupt_mod!( 10 embassy_hal_internal::interrupt_mod!(
11 OS_EVENT, LPUART0, LPI2C0, LPI2C1, LPI2C2, LPI2C3, LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, RTC, ADC1, 11 OS_EVENT, RTC, ADC1, GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, LPI2C0, LPI2C1, LPI2C2, LPI2C3, LPUART0, LPUART1,
12 LPUART2, LPUART3, LPUART4, LPUART5,
12 ); 13 );
13} 14}
14 15
@@ -292,6 +293,196 @@ impl InterruptExt for Adc {
292 } 293 }
293} 294}
294 295
296pub struct Gpio0;
297pub const GPIO0: Gpio0 = Gpio0;
298
299impl InterruptExt for Gpio0 {
300 /// Clear any pending GPIO0 in NVIC.
301 #[inline]
302 fn unpend(&self) {
303 cortex_m::peripheral::NVIC::unpend(Interrupt::GPIO0);
304 }
305
306 /// Set NVIC priority for GPIO0.
307 #[inline]
308 fn set_priority(&self, priority: Priority) {
309 unsafe {
310 let mut nvic = cortex_m::peripheral::Peripherals::steal().NVIC;
311 nvic.set_priority(Interrupt::GPIO0, u8::from(priority));
312 }
313 }
314
315 /// Enable GPIO0 in NVIC.
316 #[inline]
317 unsafe fn enable(&self) {
318 cortex_m::peripheral::NVIC::unmask(Interrupt::GPIO0);
319 }
320
321 /// Disable GPIO0 in NVIC.
322 #[inline]
323 unsafe fn disable(&self) {
324 cortex_m::peripheral::NVIC::mask(Interrupt::GPIO0);
325 }
326
327 /// Check if GPIO0 is pending in NVIC.
328 #[inline]
329 fn is_pending(&self) -> bool {
330 cortex_m::peripheral::NVIC::is_pending(Interrupt::GPIO0)
331 }
332}
333
334pub struct Gpio1;
335pub const GPIO1: Gpio1 = Gpio1;
336
337impl InterruptExt for Gpio1 {
338 /// Clear any pending GPIO1 in NVIC.
339 #[inline]
340 fn unpend(&self) {
341 cortex_m::peripheral::NVIC::unpend(Interrupt::GPIO1);
342 }
343
344 /// Set NVIC priority for GPIO1.
345 #[inline]
346 fn set_priority(&self, priority: Priority) {
347 unsafe {
348 let mut nvic = cortex_m::peripheral::Peripherals::steal().NVIC;
349 nvic.set_priority(Interrupt::GPIO1, u8::from(priority));
350 }
351 }
352
353 /// Enable GPIO1 in NVIC.
354 #[inline]
355 unsafe fn enable(&self) {
356 cortex_m::peripheral::NVIC::unmask(Interrupt::GPIO1);
357 }
358
359 /// Disable GPIO1 in NVIC.
360 #[inline]
361 unsafe fn disable(&self) {
362 cortex_m::peripheral::NVIC::mask(Interrupt::GPIO1);
363 }
364
365 /// Check if GPIO1 is pending in NVIC.
366 #[inline]
367 fn is_pending(&self) -> bool {
368 cortex_m::peripheral::NVIC::is_pending(Interrupt::GPIO1)
369 }
370}
371
372pub struct Gpio2;
373pub const GPIO2: Gpio2 = Gpio2;
374
375impl InterruptExt for Gpio2 {
376 /// Clear any pending GPIO2 in NVIC.
377 #[inline]
378 fn unpend(&self) {
379 cortex_m::peripheral::NVIC::unpend(Interrupt::GPIO2);
380 }
381
382 /// Set NVIC priority for GPIO2.
383 #[inline]
384 fn set_priority(&self, priority: Priority) {
385 unsafe {
386 let mut nvic = cortex_m::peripheral::Peripherals::steal().NVIC;
387 nvic.set_priority(Interrupt::GPIO2, u8::from(priority));
388 }
389 }
390
391 /// Enable GPIO2 in NVIC.
392 #[inline]
393 unsafe fn enable(&self) {
394 cortex_m::peripheral::NVIC::unmask(Interrupt::GPIO2);
395 }
396
397 /// Disable GPIO2 in NVIC.
398 #[inline]
399 unsafe fn disable(&self) {
400 cortex_m::peripheral::NVIC::mask(Interrupt::GPIO2);
401 }
402
403 /// Check if GPIO2 is pending in NVIC.
404 #[inline]
405 fn is_pending(&self) -> bool {
406 cortex_m::peripheral::NVIC::is_pending(Interrupt::GPIO2)
407 }
408}
409
410pub struct Gpio3;
411pub const GPIO3: Gpio3 = Gpio3;
412
413impl InterruptExt for Gpio3 {
414 /// Clear any pending GPIO3 in NVIC.
415 #[inline]
416 fn unpend(&self) {
417 cortex_m::peripheral::NVIC::unpend(Interrupt::GPIO3);
418 }
419
420 /// Set NVIC priority for GPIO3.
421 #[inline]
422 fn set_priority(&self, priority: Priority) {
423 unsafe {
424 let mut nvic = cortex_m::peripheral::Peripherals::steal().NVIC;
425 nvic.set_priority(Interrupt::GPIO3, u8::from(priority));
426 }
427 }
428
429 /// Enable GPIO3 in NVIC.
430 #[inline]
431 unsafe fn enable(&self) {
432 cortex_m::peripheral::NVIC::unmask(Interrupt::GPIO3);
433 }
434
435 /// Disable GPIO3 in NVIC.
436 #[inline]
437 unsafe fn disable(&self) {
438 cortex_m::peripheral::NVIC::mask(Interrupt::GPIO3);
439 }
440
441 /// Check if GPIO3 is pending in NVIC.
442 #[inline]
443 fn is_pending(&self) -> bool {
444 cortex_m::peripheral::NVIC::is_pending(Interrupt::GPIO3)
445 }
446}
447
448pub struct Gpio4;
449pub const GPIO4: Gpio4 = Gpio4;
450
451impl InterruptExt for Gpio4 {
452 /// Clear any pending GPIO4 in NVIC.
453 #[inline]
454 fn unpend(&self) {
455 cortex_m::peripheral::NVIC::unpend(Interrupt::GPIO4);
456 }
457
458 /// Set NVIC priority for GPIO4.
459 #[inline]
460 fn set_priority(&self, priority: Priority) {
461 unsafe {
462 let mut nvic = cortex_m::peripheral::Peripherals::steal().NVIC;
463 nvic.set_priority(Interrupt::GPIO4, u8::from(priority));
464 }
465 }
466
467 /// Enable GPIO4 in NVIC.
468 #[inline]
469 unsafe fn enable(&self) {
470 cortex_m::peripheral::NVIC::unmask(Interrupt::GPIO4);
471 }
472
473 /// Disable GPIO4 in NVIC.
474 #[inline]
475 unsafe fn disable(&self) {
476 cortex_m::peripheral::NVIC::mask(Interrupt::GPIO4);
477 }
478
479 /// Check if GPIO4 is pending in NVIC.
480 #[inline]
481 fn is_pending(&self) -> bool {
482 cortex_m::peripheral::NVIC::is_pending(Interrupt::GPIO4)
483 }
484}
485
295/// Set VTOR (Vector Table Offset) to a RAM-based vector table. 486/// Set VTOR (Vector Table Offset) to a RAM-based vector table.
296/// Pass a pointer to the first word in the RAM table (stack pointer slot 0). 487/// Pass a pointer to the first word in the RAM table (stack pointer slot 0).
297/// Safety: Caller must ensure the RAM table is valid and aligned as required by the core. 488/// Safety: Caller must ensure the RAM table is valid and aligned as required by the core.