Skip to content

Fix RP2xxx I2SOut reversed channels #10250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 21, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 129 additions & 104 deletions ports/raspberrypi/common-hal/audiobusio/I2SOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,122 +19,147 @@
#include "bindings/rp2pio/StateMachine.h"

const uint16_t i2s_program[] = {
// ; Load the next set of samples
// ; /--- LRCLK
// ; |/-- BCLK
// ; ||
// pull noblock side 0b01 ; Loads OSR with the next FIFO value or X
0x8880,
// mov x osr side 0b01 ; Save the new value in case we need it again
0xa827,
// set y 14 side 0b01
0xe84e,
// bitloop1:
// out pins 1 side 0b00 [2]
0x6201,
// jmp y-- bitloop1 side 0b01 [2]
0x0a83,
// out pins 1 side 0b10 [2]
0x7201,
// set y 14 side 0b11 [2]
0xfa4e,
// bitloop0:
// out pins 1 side 0b10 [2]
0x7201,
// jmp y-- bitloop0 side 0b11 [2]
0x1a87,
// out pins 1 side 0b00 [2]
0x6201
/*
.program i2s
.side_set 2

; Load the next set of samples
; /--- LRCLK
; |/-- BCLK
; ||
pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
mov x osr side 0b11 ; Save the new value in case we need it again
set y 14 side 0b11
bitloop1:
out pins 1 side 0b10 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b00 [2]
set y 14 side 0b01 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b01 [2]
out pins 1 side 0b10 [2]
*/
// Above assembled with pioasm.
0x9880, // 0: pull noblock side 3
0xb827, // 1: mov x, osr side 3
0xf84e, // 2: set y, 14 side 3
0x7201, // 3: out pins, 1 side 2 [2]
0x1a83, // 4: jmp y--, 3 side 3 [2]
0x6201, // 5: out pins, 1 side 0 [2]
0xea4e, // 6: set y, 14 side 1 [2]
0x6201, // 7: out pins, 1 side 0 [2]
0x0a87, // 8: jmp y--, 7 side 1 [2]
0x7201, // 9: out pins, 1 side 2 [2]
};


const uint16_t i2s_program_left_justified[] = {
// ; Load the next set of samples
// ; /--- LRCLK
// ; |/-- BCLK
// ; ||
// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
0x9880,
// mov x osr side 0b11 ; Save the new value in case we need it again
0xb827,
// set y 14 side 0b11
0xf84e,
// bitloop1:
// out pins 1 side 0b00 [2]
0x6201,
// jmp y-- bitloop1 side 0b01 [2]
0x0a83,
// out pins 1 side 0b00 [2]
0x6201,
// set y 14 side 0b01 [2]
0xea4e,
// bitloop0:
// out pins 1 side 0b10 [2]
0x7201,
// jmp y-- bitloop0 side 0b11 [2]
0x1a87,
// out pins 1 side 0b10 [2]
0x7201
/*
.program i2s
.side_set 2

; Load the next set of samples
; /--- LRCLK
; |/-- BCLK
; ||
pull noblock side 0b01 ; Loads OSR with the next FIFO value or X
mov x osr side 0b01 ; Save the new value in case we need it again
set y 14 side 0b01
bitloop1:
out pins 1 side 0b10 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b10 [2]
set y 14 side 0b11 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b01 [2]
out pins 1 side 0b00 [2]
*/
// Above assembled with pioasm.
0x8880, // 0: pull noblock side 1
0xa827, // 1: mov x, osr side 1
0xe84e, // 2: set y, 14 side 1
0x7201, // 3: out pins, 1 side 2 [2]
0x1a83, // 4: jmp y--, 3 side 3 [2]
0x7201, // 5: out pins, 1 side 2 [2]
0xfa4e, // 6: set y, 14 side 3 [2]
0x6201, // 7: out pins, 1 side 0 [2]
0x0a87, // 8: jmp y--, 7 side 1 [2]
0x6201, // 9: out pins, 1 side 0 [2]
};

// Another version of i2s_program with the LRCLC and BCLK pin swapped
const uint16_t i2s_program_swap[] = {
// ; Load the next set of samples
// ; /--- BCLK
// ; |/-- LRCLK
// ; ||
// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
0x9880,
// mov x osr side 0b11 ; Save the new value in case we need it again
0xb827,
// set y 14 side 0b11
0xf84e,
// bitloop1:
// out pins 1 side 0b01 [2]
0x6a01,
// jmp y-- bitloop1 side 0b11 [2]
0x1a83,
// out pins 1 side 0b00 [2]
0x6201,
// set y 14 side 0b10 [2]
0xf24e,
// bitloop0:
// out pins 1 side 0b00 [2]
0x6201,
// jmp y-- bitloop0 side 0b10 [2]
0x1287,
// out pins 1 side 0b01 [2]
0x6a01
/*
.program i2s
.side_set 2

; Load the next set of samples
; /--- BCLK
; |/-- LRCLK
; ||
pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
mov x osr side 0b11 ; Save the new value in case we need it again
set y 14 side 0b11
bitloop1:
out pins 1 side 0b01 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b00 [2]
set y 14 side 0b10 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b10 [2]
out pins 1 side 0b01 [2]
*/
// Above assembled with pioasm.
0x9880, // 0: pull noblock side 3
0xb827, // 1: mov x, osr side 3
0xf84e, // 2: set y, 14 side 3
0x6a01, // 3: out pins, 1 side 1 [2]
0x1a83, // 4: jmp y--, 3 side 3 [2]
0x6201, // 5: out pins, 1 side 0 [2]
0xf24e, // 6: set y, 14 side 2 [2]
0x6201, // 7: out pins, 1 side 0 [2]
0x1287, // 8: jmp y--, 7 side 2 [2]
0x6a01, // 9: out pins, 1 side 1 [2]
};

// Another version of i2s_program_left_justified with the LRCLC and BCLK pin
// swapped.
const uint16_t i2s_program_left_justified_swap[] = {
// ; Load the next set of samples
// ; /--- BCLK
// ; |/-- LRCLK
// ; ||
// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
0x9880,
// mov x osr side 0b11 ; Save the new value in case we need it again
0xb827,
// set y 14 side 0b11
0xf84e,
// bitloop1:
// out pins 1 side 0b00 [2]
0x6201,
// jmp y-- bitloop1 side 0b10 [2]
0x1283,
// out pins 1 side 0b00 [2]
0x6201,
// set y 14 side 0b10 [2]
0xf24e,
// bitloop0:
// out pins 1 side 0b01 [2]
0x6a01,
// jmp y-- bitloop0 side 0b11 [2]
0x1a87,
// out pins 1 side 0b01 [2]
0x6a01
/*
.program i2s
.side_set 2

; Load the next set of samples
; /--- BCLK
; |/-- LRCLK
; ||
pull noblock side 0b10 ; Loads OSR with the next FIFO value or X
mov x osr side 0b10 ; Save the new value in case we need it again
set y 14 side 0b10
bitloop1:
out pins 1 side 0b01 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b01 [2]
set y 14 side 0b11 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b10 [2]
out pins 1 side 0b00 [2]
*/
// Above assembled with pioasm.
0x9080, // 0: pull noblock side 2
0xb027, // 1: mov x, osr side 2
0xf04e, // 2: set y, 14 side 2
0x6a01, // 3: out pins, 1 side 1 [2]
0x1a83, // 4: jmp y--, 3 side 3 [2]
0x6a01, // 5: out pins, 1 side 1 [2]
0xfa4e, // 6: set y, 14 side 3 [2]
0x6201, // 7: out pins, 1 side 0 [2]
0x1287, // 8: jmp y--, 7 side 2 [2]
0x6201, // 9: out pins, 1 side 0 [2]
};

void i2sout_reset(void) {
Expand Down
1 change: 1 addition & 0 deletions ports/raspberrypi/common-hal/audiobusio/README.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.pio files right now are compiled by hand with pico-sdk/tools/pioasm and inserted into I2SOut.c
25 changes: 25 additions & 0 deletions ports/raspberrypi/common-hal/audiobusio/i2s.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; This file is part of the CircuitPython project: https://circuitpython.org
;
; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries
;
; SPDX-License-Identifier: MIT

.program i2s
.side_set 2

; Load the next set of samples
; /--- LRCLK
; |/-- BCLK
; ||
pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
mov x osr side 0b11 ; Save the new value in case we need it again
set y 14 side 0b11
bitloop1:
out pins 1 side 0b10 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b00 [2]
set y 14 side 0b01 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b01 [2]
out pins 1 side 0b10 [2]
25 changes: 25 additions & 0 deletions ports/raspberrypi/common-hal/audiobusio/i2s_left.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; This file is part of the CircuitPython project: https://circuitpython.org
;
; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries
;
; SPDX-License-Identifier: MIT

.program i2s
.side_set 2

; Load the next set of samples
; /--- LRCLK
; |/-- BCLK
; ||
pull noblock side 0b01 ; Loads OSR with the next FIFO value or X
mov x osr side 0b01 ; Save the new value in case we need it again
set y 14 side 0b01
bitloop1:
out pins 1 side 0b10 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b10 [2]
set y 14 side 0b11 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b01 [2]
out pins 1 side 0b00 [2]
25 changes: 25 additions & 0 deletions ports/raspberrypi/common-hal/audiobusio/i2s_swap.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; This file is part of the CircuitPython project: https://circuitpython.org
;
; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries
;
; SPDX-License-Identifier: MIT

.program i2s
.side_set 2

; Load the next set of samples
; /--- BCLK
; |/-- LRCLK
; ||
pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
mov x osr side 0b11 ; Save the new value in case we need it again
set y 14 side 0b11
bitloop1:
out pins 1 side 0b01 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b00 [2]
set y 14 side 0b10 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b10 [2]
out pins 1 side 0b01 [2]
25 changes: 25 additions & 0 deletions ports/raspberrypi/common-hal/audiobusio/i2s_swap_left.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; This file is part of the CircuitPython project: https://circuitpython.org
;
; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries
;
; SPDX-License-Identifier: MIT

.program i2s
.side_set 2

; Load the next set of samples
; /--- BCLK
; |/-- LRCLK
; ||
pull noblock side 0b10 ; Loads OSR with the next FIFO value or X
mov x osr side 0b10 ; Save the new value in case we need it again
set y 14 side 0b10
bitloop1:
out pins 1 side 0b01 [2] ; Right channel first
jmp y-- bitloop1 side 0b11 [2]
out pins 1 side 0b01 [2]
set y 14 side 0b11 [2]
bitloop0:
out pins 1 side 0b00 [2] ; Then left channel
jmp y-- bitloop0 side 0b10 [2]
out pins 1 side 0b00 [2]
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy