aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Perez Llamas <[email protected]>2022-11-13 01:41:32 +0100
committerChristian Perez Llamas <[email protected]>2022-11-13 01:41:32 +0100
commitd2e8794f29d3d0afef7a6bc610b2ee4a4d680643 (patch)
tree120e9e77a49561ef4552b9b9a82e49e5535c3fc7
parent122a31d20877005c7201d4e7c98da5544666dd1d (diff)
Investigating discontinuities in the signal
-rw-r--r--embassy-nrf/src/i2s.rs68
-rw-r--r--examples/nrf/src/bin/i2s.rs27
2 files changed, 66 insertions, 29 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
595pub(crate) mod sealed { 616pub(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 }
diff --git a/examples/nrf/src/bin/i2s.rs b/examples/nrf/src/bin/i2s.rs
index 53ccb3b85..7fb1ecb84 100644
--- a/examples/nrf/src/bin/i2s.rs
+++ b/examples/nrf/src/bin/i2s.rs
@@ -9,6 +9,7 @@ use core::f32::consts::PI;
9use defmt::{error, info}; 9use defmt::{error, info};
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_nrf::i2s::{MckFreq, Mode, Ratio, MODE_MASTER_16000, MODE_MASTER_8000}; 11use embassy_nrf::i2s::{MckFreq, Mode, Ratio, MODE_MASTER_16000, MODE_MASTER_8000};
12use embassy_nrf::pac::ficr::info;
12use embassy_nrf::{i2s, interrupt}; 13use embassy_nrf::{i2s, interrupt};
13use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
14 15
@@ -49,16 +50,14 @@ async fn main(_spawner: Spawner) {
49 let mut buf = AlignedBuffer([0i16; BUF_SIZE]); 50 let mut buf = AlignedBuffer([0i16; BUF_SIZE]);
50 51
51 let mut carrier = SineOsc::new(); 52 let mut carrier = SineOsc::new();
52 carrier.set_frequency(300.0, inv_sample_rate); 53 carrier.set_frequency(240.0, inv_sample_rate);
53 54
54 let mut modulator = SineOsc::new(); 55 // let mut modulator = SineOsc::new();
55 modulator.set_frequency(0.01, inv_sample_rate); 56 // modulator.set_frequency(0.01, inv_sample_rate);
56 modulator.set_amplitude(0.2); 57 // modulator.set_amplitude(0.2);
57 58
58 i2s.set_tx_enabled(true); 59 let mut lastf = 0.0;
59 i2s.start(); 60 let mut generate = |buf: &mut [i16]| {
60
61 loop {
62 for sample in buf.as_mut().chunks_mut(2) { 61 for sample in buf.as_mut().chunks_mut(2) {
63 let signal = carrier.generate(); 62 let signal = carrier.generate();
64 // let modulation = bipolar_to_unipolar(modulator.generate()); 63 // let modulation = bipolar_to_unipolar(modulator.generate());
@@ -67,8 +66,18 @@ async fn main(_spawner: Spawner) {
67 let value = (i16::MAX as f32 * signal) as i16; 66 let value = (i16::MAX as f32 * signal) as i16;
68 sample[0] = value; 67 sample[0] = value;
69 sample[1] = value; 68 sample[1] = value;
70 // info!("{}", signal);
71 } 69 }
70 };
71
72 generate(buf.as_mut().as_mut_slice());
73
74 i2s.set_tx_enabled(true);
75 i2s.start();
76
77 loop {
78 // info!("--");
79
80 generate(buf.as_mut().as_mut_slice());
72 81
73 if let Err(err) = i2s.tx(buf.as_ref().as_slice()).await { 82 if let Err(err) = i2s.tx(buf.as_ref().as_slice()).await {
74 error!("{}", err); 83 error!("{}", err);