A few fixes for RP2350B I2S (#91)

* Fixes audio i2s for pins >32 / RP2350B
* Adds PICO_AUDIO_I2S_CLOCK_PINS_SWAPPED to reverse the pin order of LRCLK and BCLK
master
Jeff Epler 2025-03-28 16:49:31 -05:00 zatwierdzone przez GitHub
rodzic f05d4f7371
commit 4ccfef6fe0
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
3 zmienionych plików z 47 dodań i 3 usunięć

Wyświetl plik

@ -52,10 +52,24 @@ const audio_format_t *audio_i2s_setup(const audio_format_t *intended_audio_forma
gpio_set_function(config->clock_pin_base, func);
gpio_set_function(config->clock_pin_base + 1, func);
#if PICO_PIO_USE_GPIO_BASE
if(config->data_pin >= 32 || config->clock_pin_base + 1 >= 32) {
assert(config->data_pin >= 16 && config->clock_pin_base >= 16);
pio_set_gpio_base(audio_pio, 16);
}
#endif
uint8_t sm = shared_state.pio_sm = config->pio_sm;
pio_sm_claim(audio_pio, sm);
uint offset = pio_add_program(audio_pio, &audio_i2s_program);
const struct pio_program *program =
#if PICO_AUDIO_I2S_CLOCK_PINS_SWAPPED
&audio_i2s_swapped_program
#else
&audio_i2s_program
#endif
;
uint offset = pio_add_program(audio_pio, program);
audio_i2s_program_init(audio_pio, sm, offset, config->data_pin, config->clock_pin_base);

Wyświetl plik

@ -20,7 +20,8 @@
; but for common syslck freqs this should still give a constant word select period.
;
; One output pin is used for the data output.
; Two side-set pins are used. Bit 0 is clock, bit 1 is word select.
; Two side-set pins are used. Two versions of the program are provided, so that
; the clock and word select pins can be in either order.
; Send 16 bit words to the PIO for mono, 32 bit words for stereo
@ -42,6 +43,24 @@ bitloop0:
public entry_point:
set x, 14 side 0b11
.program audio_i2s_swapped
.side_set 2
; /--- BCLK
; |/-- LRCLK
bitloop1: ; ||
out pins, 1 side 0b01
jmp x-- bitloop1 side 0b11
out pins, 1 side 0b00
set x, 14 side 0b10
bitloop0:
out pins, 1 side 0b00
jmp x-- bitloop0 side 0b10
out pins, 1 side 0b01
public entry_point:
set x, 14 side 0b11
% c-sdk {
static inline void audio_i2s_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clock_pin_base) {
@ -54,8 +73,13 @@ static inline void audio_i2s_program_init(PIO pio, uint sm, uint offset, uint da
pio_sm_init(pio, sm, offset, &sm_config);
uint pin_mask = (1u << data_pin) | (3u << clock_pin_base);
#if PICO_PIO_USE_GPIO_BASE
uint64_t pin_mask = (1ull << data_pin) | (3ull << clock_pin_base);
pio_sm_set_pindirs_with_mask64(pio, sm, pin_mask, pin_mask);
#else
uint32_t pin_mask = (1u << data_pin) | (3u << clock_pin_base);
pio_sm_set_pindirs_with_mask(pio, sm, pin_mask, pin_mask);
#endif
pio_sm_set_pins(pio, sm, 0); // clear pins
pio_sm_exec(pio, sm, pio_encode_jmp(offset + audio_i2s_offset_entry_point));

Wyświetl plik

@ -106,6 +106,12 @@ extern "C" {
#define PICO_AUDIO_I2S_CLOCK_PIN_BASE 26
#endif
// The default order is CLOCK_PIN_BASE=LRCLK, CLOCK_PIN_BASE+1=BCLK
// The swapped order is CLOCK_PIN_BASE=BCLK, CLOCK_PIN_BASE+1=LRCLK
#ifndef PICO_AUDIO_I2S_CLOCK_PINS_SWAPPED
#define PICO_AUDIO_I2S_CLOCK_PINS_SWAPPED 0
#endif
// todo this needs to come from a build config
/** \brief Base configuration structure used when setting up
* \ingroup pico_audio_i2s