diff options
| author | Christian Perez Llamas <[email protected]> | 2022-11-13 01:41:32 +0100 |
|---|---|---|
| committer | Christian Perez Llamas <[email protected]> | 2022-11-13 01:41:32 +0100 |
| commit | d2e8794f29d3d0afef7a6bc610b2ee4a4d680643 (patch) | |
| tree | 120e9e77a49561ef4552b9b9a82e49e5535c3fc7 /embassy-nrf | |
| parent | 122a31d20877005c7201d4e7c98da5544666dd1d (diff) | |
Investigating discontinuities in the signal
Diffstat (limited to 'embassy-nrf')
| -rw-r--r-- | embassy-nrf/src/i2s.rs | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index f5e36f0dd..9a8f29e78 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs | |||
| @@ -371,21 +371,6 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 371 | self.input.rx(buffer).await | 371 | self.input.rx(buffer).await |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | fn on_interrupt(_: *mut ()) { | ||
| 375 | let r = T::regs(); | ||
| 376 | let s = T::state(); | ||
| 377 | |||
| 378 | if r.events_txptrupd.read().bits() != 0 { | ||
| 379 | s.tx_waker.wake(); | ||
| 380 | r.intenclr.write(|w| w.txptrupd().clear()); | ||
| 381 | } | ||
| 382 | |||
| 383 | if r.events_rxptrupd.read().bits() != 0 { | ||
| 384 | s.rx_waker.wake(); | ||
| 385 | r.intenclr.write(|w| w.rxptrupd().clear()); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | fn apply_config(c: &CONFIG, config: &Config) { | 374 | fn apply_config(c: &CONFIG, config: &Config) { |
| 390 | match config.mode { | 375 | match config.mode { |
| 391 | Mode::Master { freq, ratio } => { | 376 | Mode::Master { freq, ratio } => { |
| @@ -443,14 +428,36 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 443 | 428 | ||
| 444 | fn setup_interrupt(irq: PeripheralRef<'d, T::Interrupt>, r: &RegisterBlock) { | 429 | fn setup_interrupt(irq: PeripheralRef<'d, T::Interrupt>, r: &RegisterBlock) { |
| 445 | irq.set_handler(Self::on_interrupt); | 430 | irq.set_handler(Self::on_interrupt); |
| 446 | irq.set_priority(Priority::P1); // TODO review priorities | 431 | // irq.set_priority(Priority::P1); // TODO review priorities |
| 447 | irq.unpend(); | 432 | irq.unpend(); |
| 448 | irq.enable(); | 433 | irq.enable(); |
| 449 | 434 | ||
| 450 | r.intenclr.write(|w| w.rxptrupd().clear()); | 435 | r.intenclr.write(|w| w.rxptrupd().clear()); |
| 451 | r.intenclr.write(|w| w.txptrupd().clear()); | 436 | r.intenclr.write(|w| w.txptrupd().clear()); |
| 437 | |||
| 452 | r.events_rxptrupd.reset(); | 438 | r.events_rxptrupd.reset(); |
| 453 | r.events_txptrupd.reset(); | 439 | r.events_txptrupd.reset(); |
| 440 | |||
| 441 | r.intenset.write(|w| w.rxptrupd().set()); | ||
| 442 | r.intenset.write(|w| w.txptrupd().set()); | ||
| 443 | } | ||
| 444 | |||
| 445 | fn on_interrupt(_: *mut ()) { | ||
| 446 | let r = T::regs(); | ||
| 447 | let s = T::state(); | ||
| 448 | |||
| 449 | if r.events_txptrupd.read().bits() != 0 { | ||
| 450 | trace!("[{}] INT", s.seq.load(Ordering::Relaxed)); | ||
| 451 | s.tx_waker.wake(); | ||
| 452 | r.intenclr.write(|w| w.txptrupd().clear()); | ||
| 453 | } | ||
| 454 | |||
| 455 | if r.events_rxptrupd.read().bits() != 0 { | ||
| 456 | s.rx_waker.wake(); | ||
| 457 | r.intenclr.write(|w| w.rxptrupd().clear()); | ||
| 458 | } | ||
| 459 | |||
| 460 | s.overruns.fetch_add(1, Ordering::Relaxed); | ||
| 454 | } | 461 | } |
| 455 | } | 462 | } |
| 456 | 463 | ||
| @@ -479,6 +486,12 @@ impl<'d, T: Instance> I2sOutput<'d, T> { | |||
| 479 | let r = T::regs(); | 486 | let r = T::regs(); |
| 480 | let s = T::state(); | 487 | let s = T::state(); |
| 481 | 488 | ||
| 489 | let seq = s.seq.fetch_add(1, Ordering::Relaxed); | ||
| 490 | if r.events_txptrupd.read().bits() != 0 && seq > 0 { | ||
| 491 | info!("XRUN!"); | ||
| 492 | loop {} | ||
| 493 | } | ||
| 494 | |||
| 482 | let drop = OnDrop::new(move || { | 495 | let drop = OnDrop::new(move || { |
| 483 | trace!("write drop: stopping"); | 496 | trace!("write drop: stopping"); |
| 484 | 497 | ||
| @@ -491,18 +504,26 @@ impl<'d, T: Instance> I2sOutput<'d, T> { | |||
| 491 | trace!("write drop: stopped"); | 504 | trace!("write drop: stopped"); |
| 492 | }); | 505 | }); |
| 493 | 506 | ||
| 507 | trace!("[{}] PTR", s.seq.load(Ordering::Relaxed)); | ||
| 494 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 508 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); |
| 495 | r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) }); | 509 | r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) }); |
| 496 | 510 | ||
| 497 | r.intenset.write(|w| w.txptrupd().set()); | ||
| 498 | |||
| 499 | compiler_fence(Ordering::SeqCst); | 511 | compiler_fence(Ordering::SeqCst); |
| 500 | 512 | ||
| 501 | poll_fn(|cx| { | 513 | poll_fn(|cx| { |
| 502 | s.tx_waker.register(cx.waker()); | 514 | s.tx_waker.register(cx.waker()); |
| 503 | if r.events_txptrupd.read().bits() != 0 { | 515 | if r.events_txptrupd.read().bits() != 0 || seq == 0 { |
| 516 | trace!("[{}] POLL Ready", s.seq.load(Ordering::Relaxed)); | ||
| 517 | r.events_txptrupd.reset(); | ||
| 518 | r.intenset.write(|w| w.txptrupd().set()); | ||
| 519 | let overruns = s.overruns.fetch_sub(1, Ordering::Relaxed); | ||
| 520 | if overruns - 1 != 0 { | ||
| 521 | warn!("XRUN: {}", overruns); | ||
| 522 | s.overruns.store(0, Ordering::Relaxed) | ||
| 523 | } | ||
| 504 | Poll::Ready(()) | 524 | Poll::Ready(()) |
| 505 | } else { | 525 | } else { |
| 526 | trace!("[{}] POLL Pending", s.seq.load(Ordering::Relaxed)); | ||
| 506 | Poll::Pending | 527 | Poll::Pending |
| 507 | } | 528 | } |
| 508 | }) | 529 | }) |
| @@ -593,19 +614,26 @@ impl Buffer for &[i32] { | |||
| 593 | } | 614 | } |
| 594 | 615 | ||
| 595 | pub(crate) mod sealed { | 616 | pub(crate) mod sealed { |
| 617 | use core::sync::atomic::AtomicI32; | ||
| 618 | |||
| 596 | use embassy_sync::waitqueue::AtomicWaker; | 619 | use embassy_sync::waitqueue::AtomicWaker; |
| 597 | 620 | ||
| 598 | //use super::*; | 621 | use super::*; |
| 599 | 622 | ||
| 600 | pub struct State { | 623 | pub struct State { |
| 601 | pub rx_waker: AtomicWaker, | 624 | pub rx_waker: AtomicWaker, |
| 602 | pub tx_waker: AtomicWaker, | 625 | pub tx_waker: AtomicWaker, |
| 626 | pub overruns: AtomicI32, | ||
| 627 | pub seq: AtomicI32, | ||
| 603 | } | 628 | } |
| 629 | |||
| 604 | impl State { | 630 | impl State { |
| 605 | pub const fn new() -> Self { | 631 | pub const fn new() -> Self { |
| 606 | Self { | 632 | Self { |
| 607 | rx_waker: AtomicWaker::new(), | 633 | rx_waker: AtomicWaker::new(), |
| 608 | tx_waker: AtomicWaker::new(), | 634 | tx_waker: AtomicWaker::new(), |
| 635 | overruns: AtomicI32::new(0), | ||
| 636 | seq: AtomicI32::new(0), | ||
| 609 | } | 637 | } |
| 610 | } | 638 | } |
| 611 | } | 639 | } |
