Skip to content

Commit ef685b1

Browse files
authored
Merge pull request #9097 from wee-noise-makers/rp2_i2s_sawp
rp2 I2SOut: support both order for BCLK and LRCLK pins
2 parents a6c6d09 + 529abf5 commit ef685b1

File tree

1 file changed

+90
-11
lines changed
  • ports/raspberrypi/common-hal/audiobusio

1 file changed

+90
-11
lines changed

ports/raspberrypi/common-hal/audiobusio/I2SOut.c

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ const uint16_t i2s_program_left_justified[] = {
8383
0x6201,
8484
// jmp y-- bitloop1 side 0b01 [2]
8585
0x0a83,
86-
// out pins 1 side 0b10 [2]
86+
// out pins 1 side 0b00 [2]
8787
0x6201,
8888
// set y 14 side 0b01 [2]
8989
0xea4e,
@@ -96,6 +96,67 @@ const uint16_t i2s_program_left_justified[] = {
9696
0x7201
9797
};
9898

99+
// Another version of i2s_program with the LRCLC and BCLK pin swapped
100+
const uint16_t i2s_program_swap[] = {
101+
// ; Load the next set of samples
102+
// ; /--- BCLK
103+
// ; |/-- LRCLK
104+
// ; ||
105+
// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
106+
0x9880,
107+
// mov x osr side 0b11 ; Save the new value in case we need it again
108+
0xb827,
109+
// set y 14 side 0b11
110+
0xf84e,
111+
// bitloop1:
112+
// out pins 1 side 0b01 [2]
113+
0x6a01,
114+
// jmp y-- bitloop1 side 0b11 [2]
115+
0x1a83,
116+
// out pins 1 side 0b00 [2]
117+
0x6201,
118+
// set y 14 side 0b10 [2]
119+
0xf24e,
120+
// bitloop0:
121+
// out pins 1 side 0b00 [2]
122+
0x6201,
123+
// jmp y-- bitloop0 side 0b10 [2]
124+
0x1287,
125+
// out pins 1 side 0b01 [2]
126+
0x6a01
127+
};
128+
129+
// Another version of i2s_program_left_justified with the LRCLC and BCLK pin
130+
// swapped.
131+
const uint16_t i2s_program_left_justified_swap[] = {
132+
// ; Load the next set of samples
133+
// ; /--- BCLK
134+
// ; |/-- LRCLK
135+
// ; ||
136+
// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X
137+
0x9880,
138+
// mov x osr side 0b11 ; Save the new value in case we need it again
139+
0xb827,
140+
// set y 14 side 0b11
141+
0xf84e,
142+
// bitloop1:
143+
// out pins 1 side 0b00 [2]
144+
0x6201,
145+
// jmp y-- bitloop1 side 0b10 [2]
146+
0x1283,
147+
// out pins 1 side 0b00 [2]
148+
0x6201,
149+
// set y 14 side 0b10 [2]
150+
0xf24e,
151+
// bitloop0:
152+
// out pins 1 side 0b01 [2]
153+
0x6a01,
154+
// jmp y-- bitloop0 side 0b11 [2]
155+
0x1a87,
156+
// out pins 1 side 0b01 [2]
157+
0x6a01
158+
};
159+
99160
void i2sout_reset(void) {
100161
}
101162

@@ -106,16 +167,34 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
106167
if (main_clock != NULL) {
107168
mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_main_clock);
108169
}
109-
if (bit_clock->number != word_select->number - 1) {
110-
mp_raise_ValueError(MP_ERROR_TEXT("Bit clock and word select must be sequential GPIO pins"));
111-
}
170+
const mcu_pin_obj_t *sideset_pin = NULL;
171+
const uint16_t *program = NULL;
172+
size_t program_len = 0;
112173

113-
const uint16_t *program = i2s_program;
114-
size_t program_len = sizeof(i2s_program) / sizeof(i2s_program[0]);
115-
if (left_justified) {
116-
program = i2s_program_left_justified;
117-
program_len = sizeof(i2s_program_left_justified) / sizeof(i2s_program_left_justified[0]);
118-
;
174+
if (bit_clock->number == word_select->number - 1) {
175+
sideset_pin = bit_clock;
176+
177+
if (left_justified) {
178+
program_len = sizeof(i2s_program_left_justified) / sizeof(i2s_program_left_justified[0]);
179+
program = i2s_program_left_justified;
180+
} else {
181+
program_len = sizeof(i2s_program) / sizeof(i2s_program[0]);
182+
program = i2s_program;
183+
}
184+
185+
} else if (bit_clock->number == word_select->number + 1) {
186+
sideset_pin = word_select;
187+
188+
if (left_justified) {
189+
program_len = sizeof(i2s_program_left_justified_swap) / sizeof(i2s_program_left_justified_swap[0]);
190+
program = i2s_program_left_justified_swap;
191+
} else {
192+
program_len = sizeof(i2s_program_swap) / sizeof(i2s_program_swap[0]);
193+
program = i2s_program_swap;
194+
}
195+
196+
} else {
197+
mp_raise_ValueError(MP_ERROR_TEXT("Bit clock and word select must be sequential GPIO pins"));
119198
}
120199

121200
// Use the state machine to manage pins.
@@ -129,7 +208,7 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
129208
NULL, 0, // in pins
130209
0, 0, // in pulls
131210
NULL, 0, 0, 0x1f, // set pins
132-
bit_clock, 2, 0, 0x1f, // sideset pins
211+
sideset_pin, 2, 0, 0x1f, // sideset pins
133212
false, // No sideset enable
134213
NULL, PULL_NONE, // jump pin
135214
0, // wait gpio pins

0 commit comments

Comments
 (0)