diff options
| author | Christian Perez Llamas <[email protected]> | 2022-11-17 00:19:22 +0100 |
|---|---|---|
| committer | Christian Perez Llamas <[email protected]> | 2022-11-17 00:19:22 +0100 |
| commit | 1ed260b1055fad6ddd89053ae3e1997ec34c6332 (patch) | |
| tree | 480475be73c6d1aa712f1a2c19bb434c1e8e64ed /examples | |
| parent | 4fe834db2f491179edf28105faf79d6fc89785c6 (diff) | |
Fix buffer overruns
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/nrf/src/bin/i2s.rs | 86 |
1 files changed, 52 insertions, 34 deletions
diff --git a/examples/nrf/src/bin/i2s.rs b/examples/nrf/src/bin/i2s.rs index 4b6f8ab2d..9b3144f24 100644 --- a/examples/nrf/src/bin/i2s.rs +++ b/examples/nrf/src/bin/i2s.rs | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | // Example inspired by RTIC's I2S demo: https://github.com/nrf-rs/nrf-hal/blob/master/examples/i2s-controller-demo/src/main.rs | ||
| 2 | |||
| 3 | #![no_std] | 1 | #![no_std] |
| 4 | #![no_main] | 2 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | 3 | #![feature(type_alias_impl_trait)] |
| 6 | 4 | ||
| 7 | use core::f32::consts::PI; | 5 | use core::f32::consts::PI; |
| 8 | 6 | ||
| 9 | use defmt::{error, info}; | 7 | use defmt::{error, info, trace}; |
| 10 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 11 | use embassy_nrf::i2s::{MckFreq, Mode, Ratio, MODE_MASTER_16000, MODE_MASTER_8000, Channels}; | 9 | use embassy_nrf::gpio::{Input, Pin, Pull}; |
| 10 | use embassy_nrf::i2s::{Channels, MckFreq, Mode, Ratio, SampleWidth, MODE_MASTER_32000}; | ||
| 12 | use embassy_nrf::pac::ficr::info; | 11 | use embassy_nrf::pac::ficr::info; |
| 13 | use embassy_nrf::{i2s, interrupt}; | 12 | use embassy_nrf::{i2s, interrupt}; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -32,60 +31,79 @@ impl<T> AsMut<T> for AlignedBuffer<T> { | |||
| 32 | async fn main(_spawner: Spawner) { | 31 | async fn main(_spawner: Spawner) { |
| 33 | let p = embassy_nrf::init(Default::default()); | 32 | let p = embassy_nrf::init(Default::default()); |
| 34 | let mut config = i2s::Config::default(); | 33 | let mut config = i2s::Config::default(); |
| 35 | // config.mode = MODE_MASTER_16000; | 34 | config.mode = MODE_MASTER_32000; |
| 36 | config.mode = Mode::Master { | 35 | // config.mode = Mode::Master { |
| 37 | freq: MckFreq::_32MDiv10, | 36 | // freq: MckFreq::_32MDiv10, |
| 38 | ratio: Ratio::_256x, | 37 | // ratio: Ratio::_256x, |
| 39 | }; // 12500 Hz | 38 | // }; // 12500 Hz |
| 40 | config.channels = Channels::Left; | 39 | config.channels = Channels::Left; |
| 40 | config.swidth = SampleWidth::_16bit; | ||
| 41 | let sample_rate = config.mode.sample_rate().expect("I2S Master"); | 41 | let sample_rate = config.mode.sample_rate().expect("I2S Master"); |
| 42 | let inv_sample_rate = 1.0 / sample_rate as f32; | 42 | let inv_sample_rate = 1.0 / sample_rate as f32; |
| 43 | 43 | ||
| 44 | info!("Sample rate: {}", sample_rate); | 44 | info!("Sample rate: {}", sample_rate); |
| 45 | 45 | ||
| 46 | // Wait for a button press | ||
| 47 | // let mut btn1 = Input::new(p.P1_00.degrade(), Pull::Up); | ||
| 48 | // btn1.wait_for_low().await; | ||
| 49 | |||
| 46 | let irq = interrupt::take!(I2S); | 50 | let irq = interrupt::take!(I2S); |
| 47 | let mut i2s = i2s::I2S::new(p.I2S, irq, p.P0_28, p.P0_29, p.P0_31, p.P0_11, p.P0_30, config); | 51 | let mut i2s = i2s::I2S::new(p.I2S, irq, p.P0_28, p.P0_29, p.P0_31, p.P0_11, p.P0_30, config).output(); |
| 48 | 52 | ||
| 49 | const BUF_SAMPLES: usize = 500; | 53 | type Sample = i16; |
| 50 | const BUF_SIZE: usize = BUF_SAMPLES; | 54 | const MAX_UNIPOLAR_VALUE: Sample = (1 << 15) as Sample; |
| 51 | let mut buf = AlignedBuffer([0i16; BUF_SIZE]); | 55 | const NUM_SAMPLES: usize = 2000; |
| 56 | let mut buffers: [AlignedBuffer<[Sample; NUM_SAMPLES]>; 3] = [ | ||
| 57 | AlignedBuffer([0; NUM_SAMPLES]), | ||
| 58 | AlignedBuffer([0; NUM_SAMPLES]), | ||
| 59 | AlignedBuffer([0; NUM_SAMPLES]), | ||
| 60 | ]; | ||
| 52 | 61 | ||
| 53 | let mut carrier = SineOsc::new(); | 62 | let mut carrier = SineOsc::new(); |
| 54 | carrier.set_frequency(16.0, inv_sample_rate); | ||
| 55 | 63 | ||
| 56 | // let mut modulator = SineOsc::new(); | 64 | let mut freq_mod = SineOsc::new(); |
| 57 | // modulator.set_frequency(0.01, inv_sample_rate); | 65 | freq_mod.set_frequency(8.0, inv_sample_rate); |
| 58 | // modulator.set_amplitude(0.2); | 66 | freq_mod.set_amplitude(1.0); |
| 67 | |||
| 68 | let mut amp_mod = SineOsc::new(); | ||
| 69 | amp_mod.set_frequency(4.0, inv_sample_rate); | ||
| 70 | amp_mod.set_amplitude(0.5); | ||
| 59 | 71 | ||
| 60 | let mut generate = |buf: &mut [i16]| { | 72 | let mut generate = |buf: &mut [Sample]| { |
| 61 | for sample in buf.as_mut() { | 73 | let ptr = buf as *const [Sample] as *const Sample as u32; |
| 74 | trace!("GEN: {}", ptr); | ||
| 75 | |||
| 76 | for sample in &mut buf.as_mut().chunks_mut(1) { | ||
| 62 | let signal = carrier.generate(); | 77 | let signal = carrier.generate(); |
| 63 | // let modulation = bipolar_to_unipolar(modulator.generate()); | 78 | let freq_modulation = bipolar_to_unipolar(freq_mod.generate()); |
| 64 | // carrier.set_frequency(200.0 + 100.0 * modulation, inv_sample_rate); | 79 | carrier.set_frequency(220.0 + 220.0 * freq_modulation, inv_sample_rate); |
| 65 | // carrier.set_amplitude((modulation); | 80 | let amp_modulation = bipolar_to_unipolar(amp_mod.generate()); |
| 66 | let value = (i16::MAX as f32 * signal) as i16; | 81 | carrier.set_amplitude(amp_modulation); |
| 67 | *sample = value; | 82 | let value = (MAX_UNIPOLAR_VALUE as f32 * signal) as Sample; |
| 83 | sample[0] = value; | ||
| 68 | } | 84 | } |
| 69 | }; | 85 | }; |
| 70 | 86 | ||
| 71 | generate(buf.as_mut().as_mut_slice()); | 87 | generate(buffers[0].as_mut().as_mut_slice()); |
| 88 | generate(buffers[1].as_mut().as_mut_slice()); | ||
| 72 | 89 | ||
| 73 | if let Err(err) = i2s.tx(buf.as_ref().as_slice()).await { | 90 | i2s.start(buffers[0].as_ref().as_slice()).expect("I2S Start"); |
| 74 | error!("{}", err); | ||
| 75 | } | ||
| 76 | |||
| 77 | i2s.set_tx_enabled(true); | ||
| 78 | i2s.start(); | ||
| 79 | 91 | ||
| 92 | let mut index = 1; | ||
| 80 | loop { | 93 | loop { |
| 81 | generate(buf.as_mut().as_mut_slice()); | 94 | if let Err(err) = i2s.send(buffers[index].as_ref().as_slice()).await { |
| 82 | |||
| 83 | if let Err(err) = i2s.tx(buf.as_ref().as_slice()).await { | ||
| 84 | error!("{}", err); | 95 | error!("{}", err); |
| 85 | } | 96 | } |
| 97 | |||
| 98 | index += 1; | ||
| 99 | if index >= 3 { | ||
| 100 | index = 0; | ||
| 101 | } | ||
| 102 | generate(buffers[index].as_mut().as_mut_slice()); | ||
| 86 | } | 103 | } |
| 87 | } | 104 | } |
| 88 | 105 | ||
| 106 | #[derive(Clone)] | ||
| 89 | struct SineOsc { | 107 | struct SineOsc { |
| 90 | amplitude: f32, | 108 | amplitude: f32, |
| 91 | modulo: f32, | 109 | modulo: f32, |
