diff options
| author | Christian Perez Llamas <[email protected]> | 2022-11-09 22:47:55 +0100 |
|---|---|---|
| committer | Christian Perez Llamas <[email protected]> | 2022-11-09 23:08:09 +0100 |
| commit | 356beabc3b11d78612c6958d1cfe542209e43558 (patch) | |
| tree | 9a8ae6fdb8a2f98ae16f17b8fbd45702f15ff066 | |
| parent | 3760b60db382c8c4f8d7067a8d472affa6db928b (diff) | |
Apply config
| -rw-r--r-- | embassy-nrf/src/i2s.rs | 85 | ||||
| -rw-r--r-- | examples/nrf/src/bin/i2s.rs | 2 |
2 files changed, 65 insertions, 22 deletions
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index e0fe6a6eb..8752dfdef 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs | |||
| @@ -9,11 +9,10 @@ | |||
| 9 | //use embassy_hal_common::drop::OnDrop; | 9 | //use embassy_hal_common::drop::OnDrop; |
| 10 | use embassy_hal_common::{into_ref, PeripheralRef}; | 10 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 11 | 11 | ||
| 12 | //use crate::pac::i2s::config::mcken; | ||
| 13 | |||
| 14 | //use crate::gpio::sealed::Pin as _; | 12 | //use crate::gpio::sealed::Pin as _; |
| 15 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 13 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 16 | use crate::interrupt::Interrupt; | 14 | use crate::interrupt::Interrupt; |
| 15 | use crate::pac::i2s::CONFIG; | ||
| 17 | use crate::Peripheral; | 16 | use crate::Peripheral; |
| 18 | 17 | ||
| 19 | // TODO: Define those in lib.rs somewhere else | 18 | // TODO: Define those in lib.rs somewhere else |
| @@ -40,7 +39,7 @@ pub enum Error { | |||
| 40 | #[non_exhaustive] | 39 | #[non_exhaustive] |
| 41 | pub struct Config { | 40 | pub struct Config { |
| 42 | pub ratio: Ratio, | 41 | pub ratio: Ratio, |
| 43 | pub sample_width: SampleWidth, | 42 | pub swidth: SampleWidth, |
| 44 | pub align: Align, | 43 | pub align: Align, |
| 45 | pub format: Format, | 44 | pub format: Format, |
| 46 | pub channels: Channels, | 45 | pub channels: Channels, |
| @@ -50,7 +49,7 @@ impl Default for Config { | |||
| 50 | fn default() -> Self { | 49 | fn default() -> Self { |
| 51 | Self { | 50 | Self { |
| 52 | ratio: Ratio::_32x, | 51 | ratio: Ratio::_32x, |
| 53 | sample_width: SampleWidth::_16bit, | 52 | swidth: SampleWidth::_16bit, |
| 54 | align: Align::Left, | 53 | align: Align::Left, |
| 55 | format: Format::I2S, | 54 | format: Format::I2S, |
| 56 | channels: Channels::Stereo, | 55 | channels: Channels::Stereo, |
| @@ -165,7 +164,7 @@ pub enum Mode { | |||
| 165 | /// Interface to the UARTE peripheral using EasyDMA to offload the transmission and reception workload. | 164 | /// Interface to the UARTE peripheral using EasyDMA to offload the transmission and reception workload. |
| 166 | /// | 165 | /// |
| 167 | /// For more details about EasyDMA, consult the module documentation. | 166 | /// For more details about EasyDMA, consult the module documentation. |
| 168 | pub struct I2s<'d, T: Instance> { | 167 | pub struct I2S<'d, T: Instance> { |
| 169 | output: I2sOutput<'d, T>, | 168 | output: I2sOutput<'d, T>, |
| 170 | _input: I2sInput<'d, T>, | 169 | _input: I2sInput<'d, T>, |
| 171 | } | 170 | } |
| @@ -182,7 +181,7 @@ pub struct I2sInput<'d, T: Instance> { | |||
| 182 | _p: PeripheralRef<'d, T>, | 181 | _p: PeripheralRef<'d, T>, |
| 183 | } | 182 | } |
| 184 | 183 | ||
| 185 | impl<'d, T: Instance> I2s<'d, T> { | 184 | impl<'d, T: Instance> I2S<'d, T> { |
| 186 | /// Create a new I2S | 185 | /// Create a new I2S |
| 187 | pub fn new( | 186 | pub fn new( |
| 188 | i2s: impl Peripheral<P = T> + 'd, | 187 | i2s: impl Peripheral<P = T> + 'd, |
| @@ -215,25 +214,13 @@ impl<'d, T: Instance> I2s<'d, T> { | |||
| 215 | lrck: PeripheralRef<'d, AnyPin>, | 214 | lrck: PeripheralRef<'d, AnyPin>, |
| 216 | sdin: PeripheralRef<'d, AnyPin>, | 215 | sdin: PeripheralRef<'d, AnyPin>, |
| 217 | sdout: PeripheralRef<'d, AnyPin>, | 216 | sdout: PeripheralRef<'d, AnyPin>, |
| 218 | _config: Config, | 217 | config: Config, |
| 219 | ) -> Self { | 218 | ) -> Self { |
| 220 | into_ref!( | 219 | into_ref!(i2s, /* irq, */ mck, sck, lrck, sdin, sdout); |
| 221 | i2s, // irq, | ||
| 222 | mck, sck, lrck, sdin, sdout | ||
| 223 | ); | ||
| 224 | 220 | ||
| 225 | let r = T::regs(); | 221 | let r = T::regs(); |
| 226 | 222 | ||
| 227 | // TODO get configuration rather than hardcoding ratio, swidth, align, format, channels | 223 | Self::apply_config(&r.config, &config); |
| 228 | |||
| 229 | r.config.mcken.write(|w| w.mcken().enabled()); | ||
| 230 | r.config.mckfreq.write(|w| w.mckfreq()._32mdiv16()); | ||
| 231 | r.config.ratio.write(|w| w.ratio()._192x()); | ||
| 232 | r.config.mode.write(|w| w.mode().master()); | ||
| 233 | r.config.swidth.write(|w| w.swidth()._16bit()); | ||
| 234 | r.config.align.write(|w| w.align().left()); | ||
| 235 | r.config.format.write(|w| w.format().i2s()); | ||
| 236 | r.config.channels.write(|w| w.channels().stereo()); | ||
| 237 | 224 | ||
| 238 | r.psel.mck.write(|w| { | 225 | r.psel.mck.write(|w| { |
| 239 | unsafe { w.bits(mck.psel_bits()) }; | 226 | unsafe { w.bits(mck.psel_bits()) }; |
| @@ -325,6 +312,62 @@ impl<'d, T: Instance> I2s<'d, T> { | |||
| 325 | pub async fn tx(&mut self, ptr: *const u8, len: usize) -> Result<(), Error> { | 312 | pub async fn tx(&mut self, ptr: *const u8, len: usize) -> Result<(), Error> { |
| 326 | self.output.tx(ptr, len).await | 313 | self.output.tx(ptr, len).await |
| 327 | } | 314 | } |
| 315 | |||
| 316 | fn apply_config(c: &CONFIG, config: &Config) { | ||
| 317 | // TODO support slave too | ||
| 318 | c.mcken.write(|w| w.mcken().enabled()); | ||
| 319 | c.mckfreq.write(|w| w.mckfreq()._32mdiv16()); | ||
| 320 | c.mode.write(|w| w.mode().master()); | ||
| 321 | |||
| 322 | c.ratio.write(|w| { | ||
| 323 | let ratio = w.ratio(); | ||
| 324 | match config.ratio { | ||
| 325 | Ratio::_32x => ratio._32x(), | ||
| 326 | Ratio::_48x => ratio._48x(), | ||
| 327 | Ratio::_64x => ratio._64x(), | ||
| 328 | Ratio::_96x => ratio._96x(), | ||
| 329 | Ratio::_128x => ratio._128x(), | ||
| 330 | Ratio::_192x => ratio._192x(), | ||
| 331 | Ratio::_256x => ratio._256x(), | ||
| 332 | Ratio::_384x => ratio._384x(), | ||
| 333 | Ratio::_512x => ratio._512x(), | ||
| 334 | } | ||
| 335 | }); | ||
| 336 | |||
| 337 | c.swidth.write(|w| { | ||
| 338 | let swidth = w.swidth(); | ||
| 339 | match config.swidth { | ||
| 340 | SampleWidth::_8bit => swidth._8bit(), | ||
| 341 | SampleWidth::_16bit => swidth._16bit(), | ||
| 342 | SampleWidth::_24bit => swidth._24bit(), | ||
| 343 | } | ||
| 344 | }); | ||
| 345 | |||
| 346 | c.align.write(|w| { | ||
| 347 | let align = w.align(); | ||
| 348 | match config.align { | ||
| 349 | Align::Left => align.left(), | ||
| 350 | Align::Right => align.right(), | ||
| 351 | } | ||
| 352 | }); | ||
| 353 | |||
| 354 | c.format.write(|w| { | ||
| 355 | let format = w.format(); | ||
| 356 | match config.format { | ||
| 357 | Format::I2S => format.i2s(), | ||
| 358 | Format::Aligned => format.aligned(), | ||
| 359 | } | ||
| 360 | }); | ||
| 361 | |||
| 362 | c.channels.write(|w| { | ||
| 363 | let channels = w.channels(); | ||
| 364 | match config.channels { | ||
| 365 | Channels::Stereo => channels.stereo(), | ||
| 366 | Channels::Left => channels.left(), | ||
| 367 | Channels::Right => channels.right(), | ||
| 368 | } | ||
| 369 | }); | ||
| 370 | } | ||
| 328 | } | 371 | } |
| 329 | 372 | ||
| 330 | impl<'d, T: Instance> I2sOutput<'d, T> { | 373 | impl<'d, T: Instance> I2sOutput<'d, T> { |
diff --git a/examples/nrf/src/bin/i2s.rs b/examples/nrf/src/bin/i2s.rs index 60cde3b65..a395c7141 100644 --- a/examples/nrf/src/bin/i2s.rs +++ b/examples/nrf/src/bin/i2s.rs | |||
| @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let p = embassy_nrf::init(Default::default()); | 17 | let p = embassy_nrf::init(Default::default()); |
| 18 | let config = i2s::Config::default(); | 18 | let config = i2s::Config::default(); |
| 19 | 19 | ||
| 20 | let mut i2s = i2s::I2s::new(p.I2S, p.P0_28, p.P0_29, p.P0_31, p.P0_11, p.P0_30, config); | 20 | let mut i2s = i2s::I2S::new(p.I2S, p.P0_28, p.P0_29, p.P0_31, p.P0_11, p.P0_30, config); |
| 21 | 21 | ||
| 22 | let mut signal_buf: Aligned<[i16; 32]> = Aligned([0i16; 32]); | 22 | let mut signal_buf: Aligned<[i16; 32]> = Aligned([0i16; 32]); |
| 23 | let len = signal_buf.0.len() / 2; | 23 | let len = signal_buf.0.len() / 2; |
