@@ -9,6 +9,10 @@ use crate::pio::{
9
9
use crate :: Peri ;
10
10
11
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
16
pub struct PioI2sOutProgram < ' d , PIO : Instance > {
13
17
prg : LoadedProgram < ' d , PIO > ,
14
18
}
@@ -17,13 +21,13 @@ impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> {
17
21
/// Load the program into the given pio
18
22
pub fn new ( common : & mut Common < ' d , PIO > ) -> Self {
19
23
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)
22
26
"left_data:" ,
23
27
" out pins, 1 side 0b00" ,
24
28
" jmp x-- left_data side 0b01" ,
25
29
" out pins 1 side 0b10" ,
26
- " set x, 14 side 0b11" ,
30
+ " mov x, y side 0b11" ,
27
31
"right_data:" ,
28
32
" out pins 1 side 0b10" ,
29
33
" jmp x-- right_data side 0b11" ,
@@ -53,7 +57,6 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
53
57
lr_clock_pin : Peri < ' d , impl PioPin > ,
54
58
sample_rate : u32 ,
55
59
bit_depth : u32 ,
56
- channels : u32 ,
57
60
program : & PioI2sOutProgram < ' d , P > ,
58
61
) -> Self {
59
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
67
let mut cfg = Config :: default ( ) ;
65
68
cfg. use_program ( & program. prg , & [ & bit_clock_pin, & left_right_clock_pin] ) ;
66
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
71
cfg. clock_divider = ( crate :: clocks:: clk_sys_freq ( ) as f64 / clock_frequency as f64 / 2. ) . to_fixed ( ) ;
69
72
cfg. shift_out = ShiftConfig {
70
73
threshold : 32 ,
@@ -78,6 +81,11 @@ impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
78
81
sm. set_config ( & cfg) ;
79
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
89
sm. set_enable ( true ) ;
82
90
83
91
Self { dma : dma. into ( ) , sm }
0 commit comments