Skip to content

Commit e133147

Browse files
authored
Bi-directional I2S support (#2775)
* Initial bi-directional I2S support. * Formatting update on pioasm file. * Added loopback example. * Updated documentation. * Fix `getOverUnderflow` naming. * Revert `getOverUnderflow` naming changes. * Remove python cache file. * Remove `availableForRead`. * Updated naming convention of OverUnderflow methods. * Update constructor to prevent conflicts with existing code. * Avoid ambiguous `setDATA` in bi-directional mode. * Use only input buffer manager in `available`. * Fix input checks in `read` and `peek`. * Fix erroneous comment. * Update pio_i2s.pio to pio v1. * Change pio_i2s.pio back to pio v0.
1 parent 8482693 commit e133147

File tree

6 files changed

+417
-72
lines changed

6 files changed

+417
-72
lines changed

docs/i2s.rst

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,31 @@ I2S(INPUT)
3030
Creates an I2S input port. Needs to be connected up to the
3131
desired pins (see below) and started before any input can happen.
3232

33+
I2S(INPUT_PULLUP)
34+
~~~~~~~~~~~~~~~~~
35+
Creates a bi-directional I2S input and output port. Needs to be
36+
connected up to the desired pins (see below) and started before
37+
any input or output can happen.
38+
3339
bool setBCLK(pin_size_t pin)
3440
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3541
Sets the BCLK pin of the I2S device. The LRCLK/word clock will be ``pin + 1``
3642
due to limitations of the PIO state machines. Call this before ``I2S::begin()``
3743

3844
bool setDATA(pin_size_t pin)
3945
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40-
Sets the DOUT or DIN pin of the I2S device. Any pin may be used.
46+
Sets the DOUT or DIN pin of the I2S device. Any pin may be used. In bi-directional
47+
operation, must use ``I2S::setDOUT()`` and ``I2S::setDIN`` instead.
48+
Call before ``I2S::begin()``
49+
50+
bool setDOUT(pin_size_t pin)
51+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52+
Sets the DOUT pin of the I2S device. Any pin may be used.
53+
Call before ``I2S::begin()``
54+
55+
bool setDIN(pin_size_t pin)
56+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57+
Sets the DIN pin of the I2S device. Any pin may be used.
4158
Call before ``I2S::begin()``
4259

4360
bool setMCLK(pin_size_t pin)
@@ -115,6 +132,14 @@ void getOverUnderflow()
115132
Returns a flag indicating if the I2S system ran our of data to send on output,
116133
or had to throw away data on input.
117134

135+
void getOverflow()
136+
~~~~~~~~~~~~~~~~~~~~~~~
137+
Returns a flag indicating if the I2S system had to throw away data on input.
138+
139+
void getUnderflow()
140+
~~~~~~~~~~~~~~~~~~~~~~~
141+
Returns a flag indicating if the I2S system ran our of data to send on output.
142+
118143
size_t write(uint8_t/int8_t/int16_t/int32_t)
119144
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120145
Writes a single sample of ``bitsPerSample`` to the buffer. It is up to the
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
I2S bi-directional input and output loopback example
3+
Released to the Public Domain by Cooper Dalrymple
4+
*/
5+
6+
#include <I2S.h>
7+
8+
I2S i2s(INPUT_PULLUP);
9+
10+
void setup() {
11+
Serial.begin(115200);
12+
13+
i2s.setDOUT(0);
14+
i2s.setDIN(1);
15+
i2s.setBCLK(2); // Note: LRCLK = BCLK + 1
16+
i2s.setBitsPerSample(16);
17+
i2s.setFrequency(22050);
18+
// NOTE: The following values are known to work with the Adafruit microphone:
19+
// i2s.setBitsPerSample(32);
20+
// i2s.setFrequency(16000);
21+
i2s.begin();
22+
23+
while (1) {
24+
int16_t l, r;
25+
i2s.read16(&l, &r);
26+
i2s.write16(l, r);
27+
// NOTE: Adafruit microphone word size needs to match the BPS above.
28+
// int32_t l, r;
29+
// i2s.read32(&l, &r);
30+
// i2s.write32(l, r);
31+
}
32+
}
33+
34+
void loop() {
35+
/* Nothing here */
36+
}

0 commit comments

Comments
 (0)