@@ -193,6 +193,80 @@ static inline pio_sm_config pio_tdm_out_swap_program_get_default_config(uint off
193193}
194194#endif
195195
196+ // ------------- //
197+ // pio_tdm_inout //
198+ // ------------- //
199+
200+ #define pio_tdm_inout_wrap_target 0
201+ #define pio_tdm_inout_wrap 5
202+
203+ static const uint16_t pio_tdm_inout_program_instructions [] = {
204+ // .wrap_target
205+ 0xa922 , // 0: mov x, y side 1 [1]
206+ 0x6001 , // 1: out pins, 1 side 0
207+ 0x4001 , // 2: in pins, 1 side 0
208+ 0x1941 , // 3: jmp x--, 1 side 3 [1]
209+ 0x5001 , // 4: in pins, 1 side 2
210+ 0x7001 , // 5: out pins, 1 side 2
211+ // .wrap
212+ };
213+
214+ #if !PICO_NO_HARDWARE
215+ static const struct pio_program pio_tdm_inout_program = {
216+ .instructions = pio_tdm_inout_program_instructions ,
217+ .length = 6 ,
218+ .origin = -1 ,
219+ .pio_version = 0 ,
220+ #if PICO_PIO_VERSION > 0
221+ .used_gpio_ranges = 0x0
222+ #endif
223+ };
224+
225+ static inline pio_sm_config pio_tdm_inout_program_get_default_config (uint offset ) {
226+ pio_sm_config c = pio_get_default_sm_config ();
227+ sm_config_set_wrap (& c , offset + pio_tdm_inout_wrap_target , offset + pio_tdm_inout_wrap );
228+ sm_config_set_sideset (& c , 2 , false, false);
229+ return c ;
230+ }
231+ #endif
232+
233+ // ------------------ //
234+ // pio_tdm_inout_swap //
235+ // ------------------ //
236+
237+ #define pio_tdm_inout_swap_wrap_target 0
238+ #define pio_tdm_inout_swap_wrap 5
239+
240+ static const uint16_t pio_tdm_inout_swap_program_instructions [] = {
241+ // .wrap_target
242+ 0xb122 , // 0: mov x, y side 2 [1]
243+ 0x6001 , // 1: out pins, 1 side 0
244+ 0x4001 , // 2: in pins, 1 side 0
245+ 0x1941 , // 3: jmp x--, 1 side 3 [1]
246+ 0x4801 , // 4: in pins, 1 side 1
247+ 0x6801 , // 5: out pins, 1 side 1
248+ // .wrap
249+ };
250+
251+ #if !PICO_NO_HARDWARE
252+ static const struct pio_program pio_tdm_inout_swap_program = {
253+ .instructions = pio_tdm_inout_swap_program_instructions ,
254+ .length = 6 ,
255+ .origin = -1 ,
256+ .pio_version = 0 ,
257+ #if PICO_PIO_VERSION > 0
258+ .used_gpio_ranges = 0x0
259+ #endif
260+ };
261+
262+ static inline pio_sm_config pio_tdm_inout_swap_program_get_default_config (uint offset ) {
263+ pio_sm_config c = pio_get_default_sm_config ();
264+ sm_config_set_wrap (& c , offset + pio_tdm_inout_swap_wrap_target , offset + pio_tdm_inout_swap_wrap );
265+ sm_config_set_sideset (& c , 2 , false, false);
266+ return c ;
267+ }
268+ #endif
269+
196270// ------------ //
197271// pio_lsbj_out //
198272// ------------ //
@@ -490,6 +564,36 @@ static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint
490564 // Need to make OSR believe there's nothing left to shift out, or the 1st word will be the count we just passed in, not a sample
491565 pio_sm_exec (pio , sm , pio_encode_out (pio_osr , 32 ));
492566}
567+ static inline void pio_tdm_inout_program_init (PIO pio , uint sm , uint offset , uint data_in_pin , uint data_out_pin , uint clock_pin_base , uint bits , bool swap , uint channels ) {
568+ pio_gpio_init (pio , data_in_pin );
569+ pio_gpio_init (pio , data_out_pin );
570+ pio_gpio_init (pio , clock_pin_base );
571+ pio_gpio_init (pio , clock_pin_base + 1 );
572+ pio_sm_config c = swap ? pio_tdm_inout_swap_program_get_default_config (offset ) : pio_tdm_inout_program_get_default_config (offset );
573+ sm_config_set_in_pins (& c , data_in_pin );
574+ sm_config_set_out_pins (& c , data_out_pin , 1 );
575+ sm_config_set_sideset_pins (& c , clock_pin_base );
576+ sm_config_set_in_shift (& c , false, true, 32 );
577+ sm_config_set_out_shift (& c , false, true, 32 );
578+ sm_config_set_fifo_join (& c , PIO_FIFO_JOIN_NONE );
579+ pio_sm_init (pio , sm , offset , & c );
580+ pio_sm_set_consecutive_pindirs (pio , sm , data_in_pin , 1 , false);
581+ pio_sm_set_consecutive_pindirs (pio , sm , data_out_pin , 1 , true);
582+ pio_sm_set_consecutive_pindirs (pio , sm , clock_pin_base , 2 , true);
583+ pio_sm_set_set_pins (pio , sm , data_out_pin , 1 );
584+ pio_sm_set_set_pins (pio , sm , clock_pin_base , 2 );
585+ // Initialize PIO state for TDM
586+ // Can't set constant > 31, so push and pop/mov if needed
587+ if (bits * channels - 1 > 31 ) {
588+ pio_sm_put_blocking (pio , sm , bits * channels - 2 );
589+ pio_sm_exec (pio , sm , pio_encode_pull (false, false));
590+ pio_sm_exec (pio , sm , pio_encode_mov (pio_y , pio_osr ));
591+ } else {
592+ pio_sm_exec (pio , sm , pio_encode_set (pio_y , bits * channels - 2 ));
593+ }
594+ // Need to make OSR believe there's nothing left to shift out
595+ pio_sm_exec (pio , sm , pio_encode_out (pio_osr , 32 ));
596+ }
493597static inline void pio_lsbj_out_program_init (PIO pio , uint sm , uint offset , uint data_pin , uint clock_pin_base , uint bits , bool swap ) {
494598 pio_gpio_init (pio , data_pin );
495599 pio_gpio_init (pio , clock_pin_base );
0 commit comments