diff options
| -rw-r--r-- | embassy-rp/src/pio_programs/i2s.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs index b967f0160..7ceed3fa6 100644 --- a/embassy-rp/src/pio_programs/i2s.rs +++ b/embassy-rp/src/pio_programs/i2s.rs | |||
| @@ -9,6 +9,10 @@ use crate::pio::{ | |||
| 9 | use crate::Peri; | 9 | use crate::Peri; |
| 10 | 10 | ||
| 11 | /// This struct represents an i2s output driver program | 11 | /// This struct represents an i2s output driver program |
| 12 | /// | ||
| 13 | /// The sample bit-depth is set through scratch register `Y`. | ||
| 14 | /// `Y` has to be set to sample bit-depth - 2. | ||
| 15 | /// (14 = 16bit, 22 = 24bit, 30 = 32bit) | ||
| 12 | pub struct PioI2sOutProgram<'d, PIO: Instance> { | 16 | pub struct PioI2sOutProgram<'d, PIO: Instance> { |
| 13 | prg: LoadedProgram<'d, PIO>, | 17 | prg: LoadedProgram<'d, PIO>, |
| 14 | } | 18 | } |
| @@ -17,13 +21,13 @@ impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> { | |||
| 17 | /// Load the program into the given pio | 21 | /// Load the program into the given pio |
| 18 | pub fn new(common: &mut Common<'d, PIO>) -> Self { | 22 | pub fn new(common: &mut Common<'d, PIO>) -> Self { |
| 19 | let prg = pio::pio_asm!( | 23 | let prg = pio::pio_asm!( |
| 20 | ".side_set 2", | 24 | ".side_set 2", // side 0bWB - W = Word Clock, B = Bit Clock |
| 21 | " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock | 25 | " mov x, y side 0b01", // y stores sample depth - 2 (14 = 16bit, 22 = 24bit, 30 = 32bit) |
| 22 | "left_data:", | 26 | "left_data:", |
| 23 | " out pins, 1 side 0b00", | 27 | " out pins, 1 side 0b00", |
| 24 | " jmp x-- left_data side 0b01", | 28 | " jmp x-- left_data side 0b01", |
| 25 | " out pins 1 side 0b10", | 29 | " out pins 1 side 0b10", |
| 26 | " set x, 14 side 0b11", | 30 | " mov x, y side 0b11", |
| 27 | "right_data:", | 31 | "right_data:", |
| 28 | " out pins 1 side 0b10", | 32 | " out pins 1 side 0b10", |
| 29 | " jmp x-- right_data side 0b11", | 33 | " jmp x-- right_data side 0b11", |
| @@ -53,7 +57,6 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { | |||
| 53 | lr_clock_pin: Peri<'d, impl PioPin>, | 57 | lr_clock_pin: Peri<'d, impl PioPin>, |
| 54 | sample_rate: u32, | 58 | sample_rate: u32, |
| 55 | bit_depth: u32, | 59 | bit_depth: u32, |
| 56 | channels: u32, | ||
| 57 | program: &PioI2sOutProgram<'d, P>, | 60 | program: &PioI2sOutProgram<'d, P>, |
| 58 | ) -> Self { | 61 | ) -> Self { |
| 59 | let data_pin = common.make_pio_pin(data_pin); | 62 | let data_pin = common.make_pio_pin(data_pin); |
| @@ -64,7 +67,7 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { | |||
| 64 | let mut cfg = Config::default(); | 67 | let mut cfg = Config::default(); |
| 65 | cfg.use_program(&program.prg, &[&bit_clock_pin, &left_right_clock_pin]); | 68 | cfg.use_program(&program.prg, &[&bit_clock_pin, &left_right_clock_pin]); |
| 66 | cfg.set_out_pins(&[&data_pin]); | 69 | cfg.set_out_pins(&[&data_pin]); |
| 67 | let clock_frequency = sample_rate * bit_depth * channels; | 70 | let clock_frequency = sample_rate * bit_depth * 2; |
| 68 | cfg.clock_divider = (crate::clocks::clk_sys_freq() as f64 / clock_frequency as f64 / 2.).to_fixed(); | 71 | cfg.clock_divider = (crate::clocks::clk_sys_freq() as f64 / clock_frequency as f64 / 2.).to_fixed(); |
| 69 | cfg.shift_out = ShiftConfig { | 72 | cfg.shift_out = ShiftConfig { |
| 70 | threshold: 32, | 73 | threshold: 32, |
| @@ -78,6 +81,11 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> { | |||
| 78 | sm.set_config(&cfg); | 81 | sm.set_config(&cfg); |
| 79 | sm.set_pin_dirs(Direction::Out, &[&data_pin, &left_right_clock_pin, &bit_clock_pin]); | 82 | sm.set_pin_dirs(Direction::Out, &[&data_pin, &left_right_clock_pin, &bit_clock_pin]); |
| 80 | 83 | ||
| 84 | // Set the `y` register up to configure the sample depth | ||
| 85 | // The SM counts down to 0 and uses one clock cycle to set up the counter, | ||
| 86 | // which results in bit_depth - 2 as register value. | ||
| 87 | unsafe { sm.set_y(bit_depth - 2) }; | ||
| 88 | |||
| 81 | sm.set_enable(true); | 89 | sm.set_enable(true); |
| 82 | 90 | ||
| 83 | Self { dma: dma.into(), sm } | 91 | Self { dma: dma.into(), sm } |
