Skip to content

Commit 3ad9b73

Browse files
authored
Merge pull request #4193 from embediver/pio-i2s-bit-depth-config
embassy-rp: Make bit-depth of I2S PIO program configurable
2 parents 4126358 + 5838346 commit 3ad9b73

File tree

3 files changed

+13
-9
lines changed

3 files changed

+13
-9
lines changed

embassy-rp/src/pio_programs/i2s.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ use crate::pio::{
99
use crate::Peri;
1010

1111
/// 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)
1216
pub struct PioI2sOutProgram<'d, PIO: Instance> {
1317
prg: LoadedProgram<'d, PIO>,
1418
}
@@ -17,13 +21,13 @@ impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> {
1721
/// Load the program into the given pio
1822
pub fn new(common: &mut Common<'d, PIO>) -> Self {
1923
let prg = pio::pio_asm!(
20-
".side_set 2",
21-
" set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock
24+
".side_set 2", // 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)
2226
"left_data:",
2327
" out pins, 1 side 0b00",
2428
" jmp x-- left_data side 0b01",
2529
" out pins 1 side 0b10",
26-
" set x, 14 side 0b11",
30+
" mov x, y side 0b11",
2731
"right_data:",
2832
" out pins 1 side 0b10",
2933
" jmp x-- right_data side 0b11",
@@ -53,7 +57,6 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
5357
lr_clock_pin: Peri<'d, impl PioPin>,
5458
sample_rate: u32,
5559
bit_depth: u32,
56-
channels: u32,
5760
program: &PioI2sOutProgram<'d, P>,
5861
) -> Self {
5962
let data_pin = common.make_pio_pin(data_pin);
@@ -64,7 +67,7 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
6467
let mut cfg = Config::default();
6568
cfg.use_program(&program.prg, &[&bit_clock_pin, &left_right_clock_pin]);
6669
cfg.set_out_pins(&[&data_pin]);
67-
let clock_frequency = sample_rate * bit_depth * channels;
70+
let clock_frequency = sample_rate * bit_depth * 2;
6871
cfg.clock_divider = (crate::clocks::clk_sys_freq() as f64 / clock_frequency as f64 / 2.).to_fixed();
6972
cfg.shift_out = ShiftConfig {
7073
threshold: 32,
@@ -78,6 +81,11 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
7881
sm.set_config(&cfg);
7982
sm.set_pin_dirs(Direction::Out, &[&data_pin, &left_right_clock_pin, &bit_clock_pin]);
8083

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+
8189
sm.set_enable(true);
8290

8391
Self { dma: dma.into(), sm }

examples/rp/src/bin/pio_i2s.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs {
2727

2828
const SAMPLE_RATE: u32 = 48_000;
2929
const BIT_DEPTH: u32 = 16;
30-
const CHANNELS: u32 = 2;
3130

3231
#[embassy_executor::main]
3332
async fn main(_spawner: Spawner) {
@@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) {
5049
left_right_clock_pin,
5150
SAMPLE_RATE,
5251
BIT_DEPTH,
53-
CHANNELS,
5452
&program,
5553
);
5654

examples/rp235x/src/bin/pio_i2s.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ bind_interrupts!(struct Irqs {
2727

2828
const SAMPLE_RATE: u32 = 48_000;
2929
const BIT_DEPTH: u32 = 16;
30-
const CHANNELS: u32 = 2;
3130

3231
#[embassy_executor::main]
3332
async fn main(_spawner: Spawner) {
@@ -50,7 +49,6 @@ async fn main(_spawner: Spawner) {
5049
left_right_clock_pin,
5150
SAMPLE_RATE,
5251
BIT_DEPTH,
53-
CHANNELS,
5452
&program,
5553
);
5654

0 commit comments

Comments
 (0)