diff --git a/libraries/I2S/src/I2S.cpp b/libraries/I2S/src/I2S.cpp index 545d08d32..103dfcf95 100644 --- a/libraries/I2S/src/I2S.cpp +++ b/libraries/I2S/src/I2S.cpp @@ -66,6 +66,7 @@ I2S::I2S(PinMode direction, pin_size_t bclk, pin_size_t data, pin_size_t mclk, p _swapClocks = false; _multMCLK = 256; _isSlave = false; + _pgm = nullptr; } I2S::~I2S() { @@ -262,20 +263,94 @@ void I2S::MCLKbegin() { pio_sm_set_enabled(_pioMCLK, _smMCLK, true); } +pio_program_t *I2S::swap2SideSet(const pio_program_t *in) { + int size = (sizeof(*in) + 4) % ~3; // Round up to nearest 32b word for alignment purposes + size += in->length * sizeof(uint16_t); + uint8_t *mem = (uint8_t *)malloc(size); + memcpy(mem, in, sizeof(*in)); + pio_program_t *out = (pio_program_t *)mem; + out->instructions = (uint16_t *)(mem + ((sizeof(*in) + 4) % ~3)); // Place the insn memory right after the struct + uint16_t *dest = (uint16_t *)out->instructions; + const uint16_t *src = in->instructions; + for (int i = 0; i < in->length; i++) { + uint16_t insn = src[i]; + uint16_t a = (insn & (1 << 12)) >> 1; // Move upper sideset bit down + uint16_t b = (insn & (1 << 11)) << 1; // Move lower sideset bit up + insn &= ~((1 << 12) | (1 << 11)); + insn |= a | b; + dest[i] = insn; + } + return out; +} + + bool I2S::begin() { + if (_running) { + return false; + } + _running = true; _hasPeeked = false; _isHolding = 0; - int off = 0; - if (!_swapClocks) { - if (!_isSlave) { - _i2s = new PIOProgram(_isOutput ? (_isInput ? (_isTDM ? &pio_tdm_inout_program : &pio_i2s_inout_program) : (_isTDM ? &pio_tdm_out_program : (_isLSBJ ? &pio_lsbj_out_program : &pio_i2s_out_program))) : &pio_i2s_in_program); + + // Determine the proper base program for the PIO + // Probably should have started API with an enum/bitmask instead of bunch of flags, but we're here now... + const pio_program *pgm; + void (*init)(PIO pio, uint sm, uint offset, uint data_in_pin, uint data_out_pin, uint clock_pin_base, uint bits, uint channels); + const int _SLAVE = 1 << 0; + const int _OUTPUT = 1 << 1; + const int _INPUT = 1 << 2; + const int _TDM = 1 << 3; + const int _LSBJ = 1 << 4; + int selector = (_isSlave ? _SLAVE : 0) | (_isOutput ? _OUTPUT : 0) | (_isInput ? _INPUT : 0) | (_isTDM ? _TDM : 0) | (_isLSBJ ? _LSBJ : 0); + switch (selector) { + case _SLAVE + _OUTPUT: + if (_bps > 16) { + pgm = &pio_i2s_out_slave_32_program; } else { - _i2s = new PIOProgram(_bps > 16 ? &pio_i2s_out_slave_32_program : &pio_i2s_out_slave_16_program); + pgm = &pio_i2s_out_slave_16_program; } + init = pio_i2s_out_slave_program_init; + break; + case _OUTPUT + _INPUT + _TDM: + pgm = &pio_tdm_inout_program; + init = pio_tdm_inout_program_init; + break; + case _OUTPUT + _INPUT: + pgm = &pio_i2s_inout_program; + init = pio_i2s_inout_program_init; + break; + case _OUTPUT + _TDM: + pgm = &pio_tdm_out_program; + init = pio_tdm_out_program_init; + break; + case _OUTPUT + _LSBJ: + pgm = &pio_lsbj_out_program; + init = pio_lsbj_out_program_init; + break; + case _OUTPUT: + pgm = &pio_i2s_out_program; + init = pio_i2s_out_program_init; + break; + case _INPUT: + pgm = &pio_i2s_in_program; + init = pio_i2s_in_program_init; + break; + default: + // Unsupported combination! + _running = false; + return false; + } + + if (_swapClocks) { + // If we swap, we need to save the generated bits and free on ::end + _pgm = swap2SideSet(pgm); + _i2s = new PIOProgram(_pgm); } else { - _i2s = new PIOProgram(_isOutput ? (_isInput ? (_isTDM ? &pio_tdm_inout_swap_program : &pio_i2s_inout_swap_program) : (_isTDM ? &pio_tdm_out_swap_program : (_isLSBJ ? &pio_lsbj_out_swap_program : &pio_i2s_out_swap_program))) : &pio_i2s_in_swap_program); + _i2s = new PIOProgram(pgm); } + + // With the RP2350B there is a GPIO-base offset for PIOs, so need to pass the min/max pins to PIOProgram to set appropriately int minpin, maxpin; if (_isOutput && _isInput) { minpin = std::min(std::min((int)_pinDOUT, (int)_pinDIN), (int)_pinBCLK); @@ -287,37 +362,26 @@ bool I2S::begin() { minpin = std::min((int)_pinDIN, (int)_pinBCLK); maxpin = std::max((int)_pinDIN, (int)_pinBCLK + 1); } + + int off = 0; if (!_i2s->prepare(&_pio, &_sm, &off, minpin, maxpin - minpin + 1)) { _running = false; + free(_pgm); delete _i2s; _i2s = nullptr; return false; } - if (_isOutput) { - if (_isInput) { - if (_isTDM) { - pio_tdm_inout_program_init(_pio, _sm, off, _pinDIN, _pinDOUT, _pinBCLK, _bps, _swapClocks, _tdmChannels); - } else { - pio_i2s_inout_program_init(_pio, _sm, off, _pinDIN, _pinDOUT, _pinBCLK, _bps, _swapClocks); - } - } else if (_isTDM) { - pio_tdm_out_program_init(_pio, _sm, off, _pinDOUT, _pinBCLK, _bps, _swapClocks, _tdmChannels); - } else if (_isLSBJ) { - pio_lsbj_out_program_init(_pio, _sm, off, _pinDOUT, _pinBCLK, _bps, _swapClocks); - } else { - if (_isSlave) { - pio_i2s_out_slave_program_init(_pio, _sm, off, _pinDOUT, _pinBCLK, _bps, _swapClocks); - } else { - pio_i2s_out_program_init(_pio, _sm, off, _pinDOUT, _pinBCLK, _bps, _swapClocks); - } - } - } else { - pio_i2s_in_program_init(_pio, _sm, off, _pinDIN, _pinBCLK, _bps, _swapClocks); - } + + init(_pio, _sm, off, _pinDIN, _pinDOUT, _pinBCLK, _bps, _tdmChannels); + setFrequency(_freq); + + // Start MCLK if needed if (_MCLKenabled) { MCLKbegin(); } + + // Calculate what to send on under/overflow based on the bits if (_bps == 8) { uint8_t a = _silenceSample & 0xff; _silenceSample = (a << 24) | (a << 16) | (a << 8) | a; @@ -325,15 +389,21 @@ bool I2S::begin() { uint16_t a = _silenceSample & 0xffff; _silenceSample = (a << 16) | a; } + + // Ensure a safe minimum if no buffersize is set if (!_bufferWords) { _bufferWords = 64 * (_bps == 32 ? 2 : 1); } + + // Generate the input ARB for DMA to RAM if (_isInput) { _arbInput = new AudioBufferManager(_buffers, _bufferWords, _silenceSample, INPUT); if (!_arbInput->begin(pio_get_dreq(_pio, _sm, false), (volatile void*)&_pio->rxf[_sm])) { _running = false; delete _arbInput; _arbInput = nullptr; + free(_pgm); + _pgm = nullptr; delete _i2s; _i2s = nullptr; return false; @@ -344,6 +414,8 @@ bool I2S::begin() { _arbInput->setCallback(_cbInput); } } + + // Generate the output ARB to dump from RAM to I2S if (_isOutput) { _arbOutput = new AudioBufferManager(_buffers, _bufferWords, _silenceSample, OUTPUT); if (!_arbOutput->begin(pio_get_dreq(_pio, _sm, true), &_pio->txf[_sm])) { @@ -352,6 +424,8 @@ bool I2S::begin() { _arbOutput = nullptr; delete _arbInput; _arbInput = nullptr; + free(_pgm); + _pgm = nullptr; delete _i2s; _i2s = nullptr; return false; @@ -362,6 +436,8 @@ bool I2S::begin() { _arbOutput->setCallback(_cbOutput); } } + + // Start the ball rolling! pio_sm_set_enabled(_pio, _sm, true); return true; @@ -380,6 +456,8 @@ bool I2S::end() { _arbOutput = nullptr; delete _arbInput; _arbInput = nullptr; + free(_pgm); + _pgm = nullptr; delete _i2s; _i2s = nullptr; } diff --git a/libraries/I2S/src/I2S.h b/libraries/I2S/src/I2S.h index 1b184700d..be6f0cee7 100644 --- a/libraries/I2S/src/I2S.h +++ b/libraries/I2S/src/I2S.h @@ -182,6 +182,8 @@ class I2S : public Stream, public AudioOutputBase { AudioBufferManager *_arbInput; AudioBufferManager *_arbOutput; + pio_program_t *swap2SideSet(const pio_program_t *src); + pio_program_t *_pgm; PIOProgram *_i2s; PIOProgram *_i2sMCLK; PIO _pio, _pioMCLK; @@ -189,4 +191,5 @@ class I2S : public Stream, public AudioOutputBase { static const int I2SSYSCLK_44_1 = 135600; // 44.1, 88.2 kHz sample rates static const int I2SSYSCLK_8 = 153600; // 8k, 16, 32, 48, 96, 192 kHz + }; diff --git a/libraries/I2S/src/pio_i2s.pio b/libraries/I2S/src/pio_i2s.pio index f0e82ee73..3e8cca2a1 100644 --- a/libraries/I2S/src/pio_i2s.pio +++ b/libraries/I2S/src/pio_i2s.pio @@ -104,29 +104,6 @@ sendright: .wrap - -.program pio_i2s_out_swap -.side_set 2 ; 0 = wclk, 1=bclk - -; The C code should place (number of bits/sample - 2) in Y and -; also update the SHIFTCTRL to be 24 or 32 as appropriate - -; +----- BCLK -; |+---- WCLK - mov x, y side 0b10 -left1: - out pins, 1 side 0b00 - jmp x--, left1 side 0b10 - out pins, 1 side 0b01 ; Last bit of left has WCLK change per I2S spec - - mov x, y side 0b11 -right1: - out pins, 1 side 0b01 - jmp x--, right1 side 0b11 - out pins, 1 side 0b00 ; Last bit of right also has WCLK change - ; Loop back to beginning... - - .program pio_tdm_out .side_set 2 ; 0 = bclk, 1 = wclk ; The C code should place (number of bits - 1) in Y and update SHIFTCTRL @@ -143,22 +120,6 @@ lastbit: ; Loop back to the beginning -.program pio_tdm_out_swap -.side_set 2 ; 0 = wclk, 1 = bclk -; The C code should place (number of bits - 1) in Y and update SHIFTCTRL -; to be 32 (as per the TDM specs) -; +----- BCLK -; |+---- WCLK - mov x, y side 0b11 -bitloop: - out pins, 1 side 0b00 - jmp x-- bitloop side 0b10 - -lastbit: - out pins, 1 side 0b01 - ; Loop back to the beginning - - .program pio_tdm_inout .side_set 2 ; 0 = bclk, 1 = wclk ; The C code should place (number of bits * channels - 1) in Y and update SHIFTCTRL @@ -177,24 +138,6 @@ lastbit: ; Loop back to the beginning -.program pio_tdm_inout_swap -.side_set 2 ; 0 = bclk, 1 = wclk -; The C code should place (number of bits * channels - 1) in Y and update SHIFTCTRL -; to be 32 (as per the TDM specs) -; +----- WCLK -; |+---- BCLK - mov x, y side 0b10 [1] -bitloop: - out pins, 1 side 0b00 ; Output changes on falling edge - in pins, 1 side 0b00 ; Sample input on falling edge - jmp x-- bitloop side 0b11 [1] ; Last bit toggles WCLK to mark frame boundary - -lastbit: - in pins, 1 side 0b01 - out pins, 1 side 0b01 - ; Loop back to the beginning - - .program pio_lsbj_out .side_set 2 ; 0 = bclk, 1=wclk @@ -217,29 +160,6 @@ right1: ; Loop back to beginning... -.program pio_lsbj_out_swap -.side_set 2 ; 0 = wclk, 1=bclk - -; The C code should place (number of bits/sample - 2) in Y and -; also update the SHIFTCTRL to be 24 or 32 as appropriate - -; +----- BCLK -; |+---- WCLK - mov x, y side 0b10 -left1: - out pins, 1 side 0b01 - jmp x--, left1 side 0b11 - out pins, 1 side 0b01 - - mov x, y side 0b11 -right1: - out pins, 1 side 0b00 - jmp x--, right1 side 0b10 - out pins, 1 side 0b00 - ; Loop back to beginning... - - - .program pio_i2s_in ; Note this is the same as _out, just "in" and not "out" .side_set 2 ; 0 = bclk, 1=wclk @@ -262,29 +182,6 @@ right1: ; Loop back to beginning... -.program pio_i2s_in_swap ; Note this is the same as _out, just "in" and not "out" -.side_set 2 ; 0 = wclk, 1=bclk - -; The C code should place (number of bits/sample - 2) in Y and -; also update the SHIFTCTRL to be 24 or 32 as appropriate - -; +----- BCLK -; |+---- WCLK - mov x, y side 0b00 -left1: - in pins, 1 side 0b10 - jmp x--, left1 side 0b00 - in pins, 1 side 0b10 ;2584 LRCK stays low until BCLK goes low - - mov x, y side 0b01 -right1: - in pins, 1 side 0b11 - jmp x--, right1 side 0b01 - in pins, 1 side 0b11 ; 2584 LRCK stays high until BCLK goes low - ; Loop back to beginning... - - - .program pio_i2s_inout .side_set 2 ; 0 = bclk, 1=wclk @@ -311,76 +208,55 @@ right1: in pins, 1 side 0b01 .wrap ; Loop back to beginning... -.program pio_i2s_inout_swap ; Note this is the same as _out, just "in" and not "out" -.side_set 2 ; 0 = wclk, 1=bclk - -; The C code should place (number of bits/sample - 2) in Y and -; also update the SHIFTCTRL to be 24 or 32 as appropriate - -; +----- BCLK -; |+---- WCLK - in pins, 1 side 0b10 ; Adjust for input shift -.wrap_target - mov x, y side 0b10 -left1: - out pins, 1 side 0b00 [1] - in pins, 1 side 0b10 - jmp x--, left1 side 0b10 - out pins, 1 side 0b01 [1] ; Last bit of left has WCLK change per I2S spec - in pins, 1 side 0b11 - mov x, y side 0b11 -right1: - out pins, 1 side 0b01 [1] - in pins, 1 side 0b11 - jmp x--, right1 side 0b11 - out pins, 1 side 0b00 [1]; Last bit of right also has WCLK change - in pins, 1 side 0b10 -.wrap ; Loop back to beginning... - - % c-sdk { static inline void pio_i2s_MCLK_program_init(PIO pio, uint sm, uint offset, uint MCLK_pin) { pio_gpio_init(pio, MCLK_pin); pio_sm_set_consecutive_pindirs(pio, sm, MCLK_pin, 1, true); - pio_sm_config sm_config = pio_i2s_mclk_program_get_default_config(offset); + pio_sm_config sm_config = pio_i2s_mclk_program_get_default_config(offset); sm_config_set_set_pins(&sm_config, MCLK_pin, 1); pio_sm_init(pio, sm, offset, &sm_config); } -static inline void pio_i2s_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +#define I2S_INIT_PARAMS (PIO pio, uint sm, uint offset, uint data_in_pin, uint data_out_pin, uint clock_pin_base, uint bits, uint channels) +#define I2S_INIT_PARAMS_VOID do { (void) data_in_pin; (void) data_out_pin; (void) clock_pin_base; (void) bits; (void) channels; } while (0) + + +static inline void pio_i2s_out_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_i2s_out_swap_program_get_default_config(offset) : pio_i2s_out_program_get_default_config(offset); + pio_sm_config sm_config = pio_i2s_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_out_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); - pio_sm_set_set_pins(pio, sm, data_pin, 1); + pio_sm_set_set_pins(pio, sm, data_out_pin, 1); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits - 2)); } -static inline void pio_i2s_out_slave_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +static inline void pio_i2s_out_slave_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); // 16-bits does a pull every L+R frame. 24/32 bits do a pull every L or R side - pio_sm_config sm_config = bits > 16 ? pio_i2s_out_slave_32_program_get_default_config(offset) : pio_i2s_out_slave_16_program_get_default_config(offset); //TBD swap ? pio_i2s_out_swap_program_get_default_config(offset) : pio_i2s_out_program_get_default_config(offset); + pio_sm_config sm_config = bits > 16 ? pio_i2s_out_slave_32_program_get_default_config(offset) : pio_i2s_out_slave_16_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_in_pins(&sm_config, clock_pin_base); sm_config_set_in_pin_count(&sm_config, 2); // BLCK and LRCLK @@ -391,36 +267,36 @@ static inline void pio_i2s_out_slave_program_init(PIO pio, uint sm, uint offset, pio_sm_init(pio, sm, offset, &sm_config); - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, false); - pio_sm_set_out_pins(pio, sm, data_pin, 1); + pio_sm_set_out_pins(pio, sm, data_out_pin, 1); pio_sm_set_in_pins(pio, sm, clock_pin_base); pio_sm_exec(pio, sm, pio_encode_set(pio_x, 0)); } - -static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap, uint channels) { - pio_gpio_init(pio, data_pin); +static inline void pio_tdm_out_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_tdm_out_swap_program_get_default_config(offset) : pio_tdm_out_program_get_default_config(offset); + pio_sm_config sm_config = pio_tdm_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_out_shift(&sm_config, false, true, 32); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - //uint pin_mask = (1u << data_pin) | (3u << clock_pin_base); + //uint pin_mask = (1u << data_out_pin) | (3u << clock_pin_base); //pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask); //pio_sm_set_pins(pio, sm, 0); // clear pins - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); - pio_sm_set_set_pins(pio, sm, data_pin, 1); + pio_sm_set_set_pins(pio, sm, data_out_pin, 1); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); // Can't set constant > 31, so push and pop/mov @@ -431,13 +307,14 @@ static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32)); } -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) { +static inline void pio_tdm_inout_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; pio_gpio_init(pio, data_in_pin); pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config c = swap ? pio_tdm_inout_swap_program_get_default_config(offset) : pio_tdm_inout_program_get_default_config(offset); + pio_sm_config c = pio_tdm_inout_program_get_default_config(offset); sm_config_set_in_pins(&c, data_in_pin); sm_config_set_out_pins(&c, data_out_pin, 1); @@ -468,39 +345,41 @@ static inline void pio_tdm_inout_program_init(PIO pio, uint sm, uint offset, uin pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32)); } -static inline void pio_lsbj_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +static inline void pio_lsbj_out_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_lsbj_out_swap_program_get_default_config(offset) : pio_lsbj_out_program_get_default_config(offset); + pio_sm_config sm_config = pio_lsbj_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_out_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - //uint pin_mask = (1u << data_pin) | (3u << clock_pin_base); + //uint pin_mask = (1u << data_out_pin) | (3u << clock_pin_base); //pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask); //pio_sm_set_pins(pio, sm, 0); // clear pins - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); - pio_sm_set_set_pins(pio, sm, data_pin, 1); + pio_sm_set_set_pins(pio, sm, data_out_pin, 1); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits - 2)); } -static inline void pio_i2s_in_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +static inline void pio_i2s_in_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_in_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_i2s_in_swap_program_get_default_config(offset) : pio_i2s_in_program_get_default_config(offset); + pio_sm_config sm_config = pio_i2s_in_program_get_default_config(offset); - sm_config_set_in_pins(&sm_config, data_pin); + sm_config_set_in_pins(&sm_config, data_in_pin); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_in_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_RX); @@ -510,7 +389,7 @@ static inline void pio_i2s_in_program_init(PIO pio, uint sm, uint offset, uint d //uint pin_mask = 3u << clock_pin_base; //pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask); //pio_sm_set_pins(pio, sm, 0); // clear pins - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, false); + pio_sm_set_consecutive_pindirs(pio, sm, data_in_pin, 1, false); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); @@ -520,13 +399,14 @@ static inline void pio_i2s_in_program_init(PIO pio, uint sm, uint offset, uint d pio_sm_exec(pio, sm, pio_encode_in(pio_pins, bits - 1)); // Shift in 1st R data modulo one bit, avoiding bit shift from #2037 } -static inline void pio_i2s_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) { +static inline void pio_i2s_inout_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; pio_gpio_init(pio, data_in_pin); pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_i2s_inout_swap_program_get_default_config(offset) : pio_i2s_inout_program_get_default_config(offset); + pio_sm_config sm_config = pio_i2s_inout_program_get_default_config(offset); sm_config_set_in_pins(&sm_config, data_in_pin); sm_config_set_out_pins(&sm_config, data_out_pin, 1); diff --git a/libraries/I2S/src/pio_i2s.pio.h b/libraries/I2S/src/pio_i2s.pio.h index a1a750ffe..3be9db9a5 100644 --- a/libraries/I2S/src/pio_i2s.pio.h +++ b/libraries/I2S/src/pio_i2s.pio.h @@ -170,46 +170,6 @@ static inline pio_sm_config pio_i2s_out_slave_32_program_get_default_config(uint } #endif -// ---------------- // -// pio_i2s_out_swap // -// ---------------- // - -#define pio_i2s_out_swap_wrap_target 0 -#define pio_i2s_out_swap_wrap 7 -#define pio_i2s_out_swap_pio_version 0 - -static const uint16_t pio_i2s_out_swap_program_instructions[] = { - // .wrap_target - 0xb022, // 0: mov x, y side 2 - 0x6001, // 1: out pins, 1 side 0 - 0x1041, // 2: jmp x--, 1 side 2 - 0x6801, // 3: out pins, 1 side 1 - 0xb822, // 4: mov x, y side 3 - 0x6801, // 5: out pins, 1 side 1 - 0x1845, // 6: jmp x--, 5 side 3 - 0x6001, // 7: out pins, 1 side 0 - // .wrap -}; - -#if !PICO_NO_HARDWARE -static const struct pio_program pio_i2s_out_swap_program = { - .instructions = pio_i2s_out_swap_program_instructions, - .length = 8, - .origin = -1, - .pio_version = pio_i2s_out_swap_pio_version, -#if PICO_PIO_VERSION > 0 - .used_gpio_ranges = 0x0 -#endif -}; - -static inline pio_sm_config pio_i2s_out_swap_program_get_default_config(uint offset) { - pio_sm_config c = pio_get_default_sm_config(); - sm_config_set_wrap(&c, offset + pio_i2s_out_swap_wrap_target, offset + pio_i2s_out_swap_wrap); - sm_config_set_sideset(&c, 2, false, false); - return c; -} -#endif - // ----------- // // pio_tdm_out // // ----------- // @@ -246,42 +206,6 @@ static inline pio_sm_config pio_tdm_out_program_get_default_config(uint offset) } #endif -// ---------------- // -// pio_tdm_out_swap // -// ---------------- // - -#define pio_tdm_out_swap_wrap_target 0 -#define pio_tdm_out_swap_wrap 3 -#define pio_tdm_out_swap_pio_version 0 - -static const uint16_t pio_tdm_out_swap_program_instructions[] = { - // .wrap_target - 0xb822, // 0: mov x, y side 3 - 0x6001, // 1: out pins, 1 side 0 - 0x1041, // 2: jmp x--, 1 side 2 - 0x6801, // 3: out pins, 1 side 1 - // .wrap -}; - -#if !PICO_NO_HARDWARE -static const struct pio_program pio_tdm_out_swap_program = { - .instructions = pio_tdm_out_swap_program_instructions, - .length = 4, - .origin = -1, - .pio_version = pio_tdm_out_swap_pio_version, -#if PICO_PIO_VERSION > 0 - .used_gpio_ranges = 0x0 -#endif -}; - -static inline pio_sm_config pio_tdm_out_swap_program_get_default_config(uint offset) { - pio_sm_config c = pio_get_default_sm_config(); - sm_config_set_wrap(&c, offset + pio_tdm_out_swap_wrap_target, offset + pio_tdm_out_swap_wrap); - sm_config_set_sideset(&c, 2, false, false); - return c; -} -#endif - // ------------- // // pio_tdm_inout // // ------------- // @@ -320,44 +244,6 @@ static inline pio_sm_config pio_tdm_inout_program_get_default_config(uint offset } #endif -// ------------------ // -// pio_tdm_inout_swap // -// ------------------ // - -#define pio_tdm_inout_swap_wrap_target 0 -#define pio_tdm_inout_swap_wrap 5 -#define pio_tdm_inout_swap_pio_version 0 - -static const uint16_t pio_tdm_inout_swap_program_instructions[] = { - // .wrap_target - 0xb122, // 0: mov x, y side 2 [1] - 0x6001, // 1: out pins, 1 side 0 - 0x4001, // 2: in pins, 1 side 0 - 0x1941, // 3: jmp x--, 1 side 3 [1] - 0x4801, // 4: in pins, 1 side 1 - 0x6801, // 5: out pins, 1 side 1 - // .wrap -}; - -#if !PICO_NO_HARDWARE -static const struct pio_program pio_tdm_inout_swap_program = { - .instructions = pio_tdm_inout_swap_program_instructions, - .length = 6, - .origin = -1, - .pio_version = pio_tdm_inout_swap_pio_version, -#if PICO_PIO_VERSION > 0 - .used_gpio_ranges = 0x0 -#endif -}; - -static inline pio_sm_config pio_tdm_inout_swap_program_get_default_config(uint offset) { - pio_sm_config c = pio_get_default_sm_config(); - sm_config_set_wrap(&c, offset + pio_tdm_inout_swap_wrap_target, offset + pio_tdm_inout_swap_wrap); - sm_config_set_sideset(&c, 2, false, false); - return c; -} -#endif - // ------------ // // pio_lsbj_out // // ------------ // @@ -398,46 +284,6 @@ static inline pio_sm_config pio_lsbj_out_program_get_default_config(uint offset) } #endif -// ----------------- // -// pio_lsbj_out_swap // -// ----------------- // - -#define pio_lsbj_out_swap_wrap_target 0 -#define pio_lsbj_out_swap_wrap 7 -#define pio_lsbj_out_swap_pio_version 0 - -static const uint16_t pio_lsbj_out_swap_program_instructions[] = { - // .wrap_target - 0xb022, // 0: mov x, y side 2 - 0x6801, // 1: out pins, 1 side 1 - 0x1841, // 2: jmp x--, 1 side 3 - 0x6801, // 3: out pins, 1 side 1 - 0xb822, // 4: mov x, y side 3 - 0x6001, // 5: out pins, 1 side 0 - 0x1045, // 6: jmp x--, 5 side 2 - 0x6001, // 7: out pins, 1 side 0 - // .wrap -}; - -#if !PICO_NO_HARDWARE -static const struct pio_program pio_lsbj_out_swap_program = { - .instructions = pio_lsbj_out_swap_program_instructions, - .length = 8, - .origin = -1, - .pio_version = pio_lsbj_out_swap_pio_version, -#if PICO_PIO_VERSION > 0 - .used_gpio_ranges = 0x0 -#endif -}; - -static inline pio_sm_config pio_lsbj_out_swap_program_get_default_config(uint offset) { - pio_sm_config c = pio_get_default_sm_config(); - sm_config_set_wrap(&c, offset + pio_lsbj_out_swap_wrap_target, offset + pio_lsbj_out_swap_wrap); - sm_config_set_sideset(&c, 2, false, false); - return c; -} -#endif - // ---------- // // pio_i2s_in // // ---------- // @@ -478,46 +324,6 @@ static inline pio_sm_config pio_i2s_in_program_get_default_config(uint offset) { } #endif -// --------------- // -// pio_i2s_in_swap // -// --------------- // - -#define pio_i2s_in_swap_wrap_target 0 -#define pio_i2s_in_swap_wrap 7 -#define pio_i2s_in_swap_pio_version 0 - -static const uint16_t pio_i2s_in_swap_program_instructions[] = { - // .wrap_target - 0xa022, // 0: mov x, y side 0 - 0x5001, // 1: in pins, 1 side 2 - 0x0041, // 2: jmp x--, 1 side 0 - 0x5001, // 3: in pins, 1 side 2 - 0xa822, // 4: mov x, y side 1 - 0x5801, // 5: in pins, 1 side 3 - 0x0845, // 6: jmp x--, 5 side 1 - 0x5801, // 7: in pins, 1 side 3 - // .wrap -}; - -#if !PICO_NO_HARDWARE -static const struct pio_program pio_i2s_in_swap_program = { - .instructions = pio_i2s_in_swap_program_instructions, - .length = 8, - .origin = -1, - .pio_version = pio_i2s_in_swap_pio_version, -#if PICO_PIO_VERSION > 0 - .used_gpio_ranges = 0x0 -#endif -}; - -static inline pio_sm_config pio_i2s_in_swap_program_get_default_config(uint offset) { - pio_sm_config c = pio_get_default_sm_config(); - sm_config_set_wrap(&c, offset + pio_i2s_in_swap_wrap_target, offset + pio_i2s_in_swap_wrap); - sm_config_set_sideset(&c, 2, false, false); - return c; -} -#endif - // ------------- // // pio_i2s_inout // // ------------- // @@ -561,51 +367,6 @@ static inline pio_sm_config pio_i2s_inout_program_get_default_config(uint offset sm_config_set_sideset(&c, 2, false, false); return c; } -#endif - -// ------------------ // -// pio_i2s_inout_swap // -// ------------------ // - -#define pio_i2s_inout_swap_wrap_target 1 -#define pio_i2s_inout_swap_wrap 12 -#define pio_i2s_inout_swap_pio_version 0 - -static const uint16_t pio_i2s_inout_swap_program_instructions[] = { - 0x5001, // 0: in pins, 1 side 2 - // .wrap_target - 0xb022, // 1: mov x, y side 2 - 0x6101, // 2: out pins, 1 side 0 [1] - 0x5001, // 3: in pins, 1 side 2 - 0x1042, // 4: jmp x--, 2 side 2 - 0x6901, // 5: out pins, 1 side 1 [1] - 0x5801, // 6: in pins, 1 side 3 - 0xb822, // 7: mov x, y side 3 - 0x6901, // 8: out pins, 1 side 1 [1] - 0x5801, // 9: in pins, 1 side 3 - 0x1848, // 10: jmp x--, 8 side 3 - 0x6101, // 11: out pins, 1 side 0 [1] - 0x5001, // 12: in pins, 1 side 2 - // .wrap -}; - -#if !PICO_NO_HARDWARE -static const struct pio_program pio_i2s_inout_swap_program = { - .instructions = pio_i2s_inout_swap_program_instructions, - .length = 13, - .origin = -1, - .pio_version = pio_i2s_inout_swap_pio_version, -#if PICO_PIO_VERSION > 0 - .used_gpio_ranges = 0x0 -#endif -}; - -static inline pio_sm_config pio_i2s_inout_swap_program_get_default_config(uint offset) { - pio_sm_config c = pio_get_default_sm_config(); - sm_config_set_wrap(&c, offset + pio_i2s_inout_swap_wrap_target, offset + pio_i2s_inout_swap_wrap); - sm_config_set_sideset(&c, 2, false, false); - return c; -} static inline void pio_i2s_MCLK_program_init(PIO pio, uint sm, uint offset, uint MCLK_pin) { pio_gpio_init(pio, MCLK_pin); @@ -614,57 +375,62 @@ static inline void pio_i2s_MCLK_program_init(PIO pio, uint sm, uint offset, uint sm_config_set_set_pins(&sm_config, MCLK_pin, 1); pio_sm_init(pio, sm, offset, &sm_config); } -static inline void pio_i2s_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +#define I2S_INIT_PARAMS (PIO pio, uint sm, uint offset, uint data_in_pin, uint data_out_pin, uint clock_pin_base, uint bits, uint channels) +#define I2S_INIT_PARAMS_VOID do { (void) data_in_pin; (void) data_out_pin; (void) clock_pin_base; (void) bits; (void) channels; } while (0) +static inline void pio_i2s_out_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_i2s_out_swap_program_get_default_config(offset) : pio_i2s_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + pio_sm_config sm_config = pio_i2s_out_program_get_default_config(offset); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_out_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); - pio_sm_set_set_pins(pio, sm, data_pin, 1); + pio_sm_set_set_pins(pio, sm, data_out_pin, 1); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits - 2)); } -static inline void pio_i2s_out_slave_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +static inline void pio_i2s_out_slave_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); // 16-bits does a pull every L+R frame. 24/32 bits do a pull every L or R side - pio_sm_config sm_config = bits > 16 ? pio_i2s_out_slave_32_program_get_default_config(offset) : pio_i2s_out_slave_16_program_get_default_config(offset); //TBD swap ? pio_i2s_out_swap_program_get_default_config(offset) : pio_i2s_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + pio_sm_config sm_config = bits > 16 ? pio_i2s_out_slave_32_program_get_default_config(offset) : pio_i2s_out_slave_16_program_get_default_config(offset); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_in_pins(&sm_config, clock_pin_base); sm_config_set_in_pin_count(&sm_config, 2); // BLCK and LRCLK sm_config_set_jmp_pin(&sm_config, clock_pin_base + 1); sm_config_set_out_shift(&sm_config, false, false, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, false); - pio_sm_set_out_pins(pio, sm, data_pin, 1); + pio_sm_set_out_pins(pio, sm, data_out_pin, 1); pio_sm_set_in_pins(pio, sm, clock_pin_base); pio_sm_exec(pio, sm, pio_encode_set(pio_x, 0)); } -static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap, uint channels) { - pio_gpio_init(pio, data_pin); +static inline void pio_tdm_out_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_tdm_out_swap_program_get_default_config(offset) : pio_tdm_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + pio_sm_config sm_config = pio_tdm_out_program_get_default_config(offset); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_out_shift(&sm_config, false, true, 32); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - //uint pin_mask = (1u << data_pin) | (3u << clock_pin_base); + //uint pin_mask = (1u << data_out_pin) | (3u << clock_pin_base); //pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask); //pio_sm_set_pins(pio, sm, 0); // clear pins - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); - pio_sm_set_set_pins(pio, sm, data_pin, 1); + pio_sm_set_set_pins(pio, sm, data_out_pin, 1); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); // Can't set constant > 31, so push and pop/mov pio_sm_put_blocking(pio, sm, bits * channels - 2); @@ -673,12 +439,13 @@ static inline void pio_tdm_out_program_init(PIO pio, uint sm, uint offset, uint // 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 pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32)); } -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) { +static inline void pio_tdm_inout_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; pio_gpio_init(pio, data_in_pin); pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config c = swap ? pio_tdm_inout_swap_program_get_default_config(offset) : pio_tdm_inout_program_get_default_config(offset); + pio_sm_config c = pio_tdm_inout_program_get_default_config(offset); sm_config_set_in_pins(&c, data_in_pin); sm_config_set_out_pins(&c, data_out_pin, 1); sm_config_set_sideset_pins(&c, clock_pin_base); @@ -703,31 +470,33 @@ static inline void pio_tdm_inout_program_init(PIO pio, uint sm, uint offset, uin // Need to make OSR believe there's nothing left to shift out pio_sm_exec(pio, sm, pio_encode_out(pio_osr, 32)); } -static inline void pio_lsbj_out_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +static inline void pio_lsbj_out_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_lsbj_out_swap_program_get_default_config(offset) : pio_lsbj_out_program_get_default_config(offset); - sm_config_set_out_pins(&sm_config, data_pin, 1); + pio_sm_config sm_config = pio_lsbj_out_program_get_default_config(offset); + sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_out_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_TX); pio_sm_init(pio, sm, offset, &sm_config); - //uint pin_mask = (1u << data_pin) | (3u << clock_pin_base); + //uint pin_mask = (1u << data_out_pin) | (3u << clock_pin_base); //pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask); //pio_sm_set_pins(pio, sm, 0); // clear pins - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true); + pio_sm_set_consecutive_pindirs(pio, sm, data_out_pin, 1, true); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); - pio_sm_set_set_pins(pio, sm, data_pin, 1); + pio_sm_set_set_pins(pio, sm, data_out_pin, 1); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits - 2)); } -static inline void pio_i2s_in_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base, uint bits, bool swap) { - pio_gpio_init(pio, data_pin); +static inline void pio_i2s_in_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; + pio_gpio_init(pio, data_in_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_i2s_in_swap_program_get_default_config(offset) : pio_i2s_in_program_get_default_config(offset); - sm_config_set_in_pins(&sm_config, data_pin); + pio_sm_config sm_config = pio_i2s_in_program_get_default_config(offset); + sm_config_set_in_pins(&sm_config, data_in_pin); sm_config_set_sideset_pins(&sm_config, clock_pin_base); sm_config_set_in_shift(&sm_config, false, true, (bits <= 16) ? 2 * bits : bits); sm_config_set_fifo_join(&sm_config, PIO_FIFO_JOIN_RX); @@ -735,19 +504,20 @@ static inline void pio_i2s_in_program_init(PIO pio, uint sm, uint offset, uint d //uint pin_mask = 3u << clock_pin_base; //pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask); //pio_sm_set_pins(pio, sm, 0); // clear pins - pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, false); + pio_sm_set_consecutive_pindirs(pio, sm, data_in_pin, 1, false); pio_sm_set_consecutive_pindirs(pio, sm, clock_pin_base, 2, true); pio_sm_set_set_pins(pio, sm, clock_pin_base, 2); pio_sm_exec(pio, sm, pio_encode_set(pio_y, bits - 2)); pio_sm_exec(pio, sm, pio_encode_in(pio_pins, bits)); // Shift in 1st L data pio_sm_exec(pio, sm, pio_encode_in(pio_pins, bits - 1)); // Shift in 1st R data modulo one bit, avoiding bit shift from #2037 } -static inline void pio_i2s_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) { +static inline void pio_i2s_inout_program_init I2S_INIT_PARAMS { + I2S_INIT_PARAMS_VOID; pio_gpio_init(pio, data_in_pin); pio_gpio_init(pio, data_out_pin); pio_gpio_init(pio, clock_pin_base); pio_gpio_init(pio, clock_pin_base + 1); - pio_sm_config sm_config = swap ? pio_i2s_inout_swap_program_get_default_config(offset) : pio_i2s_inout_program_get_default_config(offset); + pio_sm_config sm_config = pio_i2s_inout_program_get_default_config(offset); sm_config_set_in_pins(&sm_config, data_in_pin); sm_config_set_out_pins(&sm_config, data_out_pin, 1); sm_config_set_sideset_pins(&sm_config, clock_pin_base);