Investigating discontinuities in the signal
This commit is contained in:
parent
122a31d208
commit
d2e8794f29
@ -371,21 +371,6 @@ impl<'d, T: Instance> I2S<'d, T> {
|
||||
self.input.rx(buffer).await
|
||||
}
|
||||
|
||||
fn on_interrupt(_: *mut ()) {
|
||||
let r = T::regs();
|
||||
let s = T::state();
|
||||
|
||||
if r.events_txptrupd.read().bits() != 0 {
|
||||
s.tx_waker.wake();
|
||||
r.intenclr.write(|w| w.txptrupd().clear());
|
||||
}
|
||||
|
||||
if r.events_rxptrupd.read().bits() != 0 {
|
||||
s.rx_waker.wake();
|
||||
r.intenclr.write(|w| w.rxptrupd().clear());
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_config(c: &CONFIG, config: &Config) {
|
||||
match config.mode {
|
||||
Mode::Master { freq, ratio } => {
|
||||
@ -443,14 +428,36 @@ impl<'d, T: Instance> I2S<'d, T> {
|
||||
|
||||
fn setup_interrupt(irq: PeripheralRef<'d, T::Interrupt>, r: &RegisterBlock) {
|
||||
irq.set_handler(Self::on_interrupt);
|
||||
irq.set_priority(Priority::P1); // TODO review priorities
|
||||
// irq.set_priority(Priority::P1); // TODO review priorities
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
|
||||
r.intenclr.write(|w| w.rxptrupd().clear());
|
||||
r.intenclr.write(|w| w.txptrupd().clear());
|
||||
|
||||
r.events_rxptrupd.reset();
|
||||
r.events_txptrupd.reset();
|
||||
|
||||
r.intenset.write(|w| w.rxptrupd().set());
|
||||
r.intenset.write(|w| w.txptrupd().set());
|
||||
}
|
||||
|
||||
fn on_interrupt(_: *mut ()) {
|
||||
let r = T::regs();
|
||||
let s = T::state();
|
||||
|
||||
if r.events_txptrupd.read().bits() != 0 {
|
||||
trace!("[{}] INT", s.seq.load(Ordering::Relaxed));
|
||||
s.tx_waker.wake();
|
||||
r.intenclr.write(|w| w.txptrupd().clear());
|
||||
}
|
||||
|
||||
if r.events_rxptrupd.read().bits() != 0 {
|
||||
s.rx_waker.wake();
|
||||
r.intenclr.write(|w| w.rxptrupd().clear());
|
||||
}
|
||||
|
||||
s.overruns.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,6 +486,12 @@ impl<'d, T: Instance> I2sOutput<'d, T> {
|
||||
let r = T::regs();
|
||||
let s = T::state();
|
||||
|
||||
let seq = s.seq.fetch_add(1, Ordering::Relaxed);
|
||||
if r.events_txptrupd.read().bits() != 0 && seq > 0 {
|
||||
info!("XRUN!");
|
||||
loop {}
|
||||
}
|
||||
|
||||
let drop = OnDrop::new(move || {
|
||||
trace!("write drop: stopping");
|
||||
|
||||
@ -491,18 +504,26 @@ impl<'d, T: Instance> I2sOutput<'d, T> {
|
||||
trace!("write drop: stopped");
|
||||
});
|
||||
|
||||
trace!("[{}] PTR", s.seq.load(Ordering::Relaxed));
|
||||
r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
|
||||
r.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) });
|
||||
|
||||
r.intenset.write(|w| w.txptrupd().set());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
poll_fn(|cx| {
|
||||
s.tx_waker.register(cx.waker());
|
||||
if r.events_txptrupd.read().bits() != 0 {
|
||||
if r.events_txptrupd.read().bits() != 0 || seq == 0 {
|
||||
trace!("[{}] POLL Ready", s.seq.load(Ordering::Relaxed));
|
||||
r.events_txptrupd.reset();
|
||||
r.intenset.write(|w| w.txptrupd().set());
|
||||
let overruns = s.overruns.fetch_sub(1, Ordering::Relaxed);
|
||||
if overruns - 1 != 0 {
|
||||
warn!("XRUN: {}", overruns);
|
||||
s.overruns.store(0, Ordering::Relaxed)
|
||||
}
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
trace!("[{}] POLL Pending", s.seq.load(Ordering::Relaxed));
|
||||
Poll::Pending
|
||||
}
|
||||
})
|
||||
@ -593,19 +614,26 @@ impl Buffer for &[i32] {
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
use core::sync::atomic::AtomicI32;
|
||||
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
//use super::*;
|
||||
use super::*;
|
||||
|
||||
pub struct State {
|
||||
pub rx_waker: AtomicWaker,
|
||||
pub tx_waker: AtomicWaker,
|
||||
pub overruns: AtomicI32,
|
||||
pub seq: AtomicI32,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
rx_waker: AtomicWaker::new(),
|
||||
tx_waker: AtomicWaker::new(),
|
||||
overruns: AtomicI32::new(0),
|
||||
seq: AtomicI32::new(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use core::f32::consts::PI;
|
||||
use defmt::{error, info};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_nrf::i2s::{MckFreq, Mode, Ratio, MODE_MASTER_16000, MODE_MASTER_8000};
|
||||
use embassy_nrf::pac::ficr::info;
|
||||
use embassy_nrf::{i2s, interrupt};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
@ -49,16 +50,14 @@ async fn main(_spawner: Spawner) {
|
||||
let mut buf = AlignedBuffer([0i16; BUF_SIZE]);
|
||||
|
||||
let mut carrier = SineOsc::new();
|
||||
carrier.set_frequency(300.0, inv_sample_rate);
|
||||
carrier.set_frequency(240.0, inv_sample_rate);
|
||||
|
||||
let mut modulator = SineOsc::new();
|
||||
modulator.set_frequency(0.01, inv_sample_rate);
|
||||
modulator.set_amplitude(0.2);
|
||||
// let mut modulator = SineOsc::new();
|
||||
// modulator.set_frequency(0.01, inv_sample_rate);
|
||||
// modulator.set_amplitude(0.2);
|
||||
|
||||
i2s.set_tx_enabled(true);
|
||||
i2s.start();
|
||||
|
||||
loop {
|
||||
let mut lastf = 0.0;
|
||||
let mut generate = |buf: &mut [i16]| {
|
||||
for sample in buf.as_mut().chunks_mut(2) {
|
||||
let signal = carrier.generate();
|
||||
// let modulation = bipolar_to_unipolar(modulator.generate());
|
||||
@ -67,8 +66,18 @@ async fn main(_spawner: Spawner) {
|
||||
let value = (i16::MAX as f32 * signal) as i16;
|
||||
sample[0] = value;
|
||||
sample[1] = value;
|
||||
// info!("{}", signal);
|
||||
}
|
||||
};
|
||||
|
||||
generate(buf.as_mut().as_mut_slice());
|
||||
|
||||
i2s.set_tx_enabled(true);
|
||||
i2s.start();
|
||||
|
||||
loop {
|
||||
// info!("--");
|
||||
|
||||
generate(buf.as_mut().as_mut_slice());
|
||||
|
||||
if let Err(err) = i2s.tx(buf.as_ref().as_slice()).await {
|
||||
error!("{}", err);
|
||||
|
Loading…
Reference in New Issue
Block a user