Skip to content

Commit 07bf0df

Browse files
authored
Merge pull request #58 from arduino-libraries/i2s_support
AdvancedI2S: Add I2S input, output and full-duplex support.
2 parents 171a789 + e97c8f3 commit 07bf0df

File tree

9 files changed

+675
-0
lines changed

9 files changed

+675
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This example demonstrates how to capture samples from an I2S mic,
2+
// and output them on a DAC.
3+
4+
#include <Arduino_AdvancedAnalog.h>
5+
6+
AdvancedDAC dac1(A12);
7+
// WS, CK, SDI, SDO, MCK
8+
AdvancedI2S i2s(PG_10, PG_11, PG_9, PB_5, PC_4);
9+
10+
#define N_SAMPLES (256)
11+
#define SAMPLE_AVERAGE(s0, s1) (((int16_t) s0 / 2) + ((int16_t) s1 / 2))
12+
13+
void setup() {
14+
Serial.begin(9600);
15+
while (!Serial) {
16+
}
17+
18+
// Resolution, sample rate, number of samples per channel, queue depth.
19+
if (!dac1.begin(AN_RESOLUTION_12, 32000, N_SAMPLES, 32)) {
20+
Serial.println("Failed to start DAC1 !");
21+
while (1);
22+
}
23+
24+
// I2S mode, sample rate, number of samples per channel, queue depth.
25+
if (!i2s.begin(AN_I2S_MODE_IN, 32000, N_SAMPLES, 32)) {
26+
Serial.println("Failed to start I2S");
27+
while (1);
28+
}
29+
}
30+
31+
void loop() {
32+
if (i2s.available() && dac1.available()) {
33+
SampleBuffer i2sbuf = i2s.read();
34+
SampleBuffer dacbuf = dac1.dequeue();
35+
36+
// Write data to buffer.
37+
for (int i=0; i<dacbuf.size(); i++) {
38+
// Average the 2 samples, map to positive and down scale to 12-bit.
39+
// Note that I2S always captures 2 channels.
40+
dacbuf[i] = ((uint32_t) (SAMPLE_AVERAGE(i2sbuf[(i * 2)], i2sbuf[(i * 2) + 1]) + 32768)) >> 4;
41+
}
42+
43+
// Write the buffer to DAC.
44+
dac1.write(dacbuf);
45+
i2sbuf.release();
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This example demonstrates I2S in full-duplex mode. In the main loop, samples
2+
// are continuously captured from the I2S input, and written back to I2S output.
3+
4+
#include <Arduino_AdvancedAnalog.h>
5+
6+
// WS, CK, SDI, SDO, MCK
7+
AdvancedI2S i2s(PG_10, PG_11, PG_9, PB_5, PC_4);
8+
9+
void setup() {
10+
Serial.begin(9600);
11+
while (!Serial) {
12+
13+
}
14+
15+
// Resolution, sample rate, number of samples per channel, queue depth.
16+
if (!i2s.begin(AN_I2S_MODE_INOUT, 32000, 512, 32)) {
17+
Serial.println("Failed to start I2S");
18+
while (1);
19+
}
20+
}
21+
22+
void loop() {
23+
if (i2s.available()) {
24+
SampleBuffer rxbuf = i2s.read();
25+
SampleBuffer txbuf = i2s.dequeue();
26+
for (size_t i=0; i<rxbuf.size(); i++) {
27+
txbuf[i] = rxbuf[i];
28+
}
29+
rxbuf.release();
30+
i2s.write(txbuf);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:9c17298498cf2a99c95f8dcf246691be4852eaddf8da24268b62854e0056c796
3+
size 1426086
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// This example demonstrates how to playback a WAV file with I2S.
2+
// To run this sketch, rename 'USB_DRIVE' to the name of your USB
3+
// stick drive, and copy the provided audio sample to the drive.
4+
#include <Arduino_AdvancedAnalog.h>
5+
#include <Arduino_USBHostMbed5.h>
6+
#include <FATFileSystem.h>
7+
#include <DigitalOut.h>
8+
#include <WavReader.h>
9+
10+
USBHostMSD msd;
11+
mbed::FATFileSystem usb("USB_DRIVE");
12+
13+
WavReader wav;
14+
// WS, CK, SDI, SDO, MCK
15+
AdvancedI2S i2s(PG_10, PG_11, PG_9, PB_5, PC_4);
16+
#define N_SAMPLES (512)
17+
18+
void setup() {
19+
Serial.begin(9600);
20+
while (!Serial) {
21+
22+
}
23+
24+
// Enable power for HOST USB connector.
25+
pinMode(PA_15, OUTPUT);
26+
digitalWrite(PA_15, HIGH);
27+
28+
Serial.println("Please connect a USB stick to the USB host port...");
29+
while (!msd.connect()) {
30+
delay(100);
31+
}
32+
33+
Serial.println("Mounting USB device...");
34+
int const rc_mount = usb.mount(&msd);
35+
if (rc_mount) {
36+
Serial.print("Error mounting USB device ");
37+
Serial.println(rc_mount);
38+
while (1);
39+
}
40+
41+
Serial.println("Opening audio file ...");
42+
if (!wav.begin("/USB_DRIVE/AUDIO_SAMPLE.wav", N_SAMPLES, 1, true)) {
43+
Serial.print("Error opening audio file: ");
44+
while (1);
45+
}
46+
47+
// Resolution, sample rate, number of samples per channel, queue depth.
48+
if (!i2s.begin(AN_I2S_MODE_OUT, wav.sample_rate(), N_SAMPLES, 64)) {
49+
Serial.println("Failed to start I2S");
50+
while (1);
51+
}
52+
Serial.println("Playing audio file ...");
53+
}
54+
55+
void loop() {
56+
if (i2s.available() && wav.available()) {
57+
// Get a free I2S buffer for writing.
58+
SampleBuffer i2s_buf = i2s.dequeue();
59+
60+
// Read a PCM samples buffer from the wav file.
61+
SampleBuffer pcm_buf = wav.read();
62+
63+
// Write PCM samples to the I2S buffer.
64+
for (size_t i = 0; i < N_SAMPLES * wav.channels(); i++) {
65+
// Note I2S buffers are always 2 channels.
66+
if (wav.channels() == 2) {
67+
i2s_buf[i] = pcm_buf[i];
68+
} else {
69+
i2s_buf[(i * 2) + 0] = ((int16_t) pcm_buf[i] / 2);
70+
i2s_buf[(i * 2) + 1] = ((int16_t) pcm_buf[i] / 2);
71+
}
72+
}
73+
74+
// Write back the I2S buffer.
75+
i2s.write(i2s_buf);
76+
77+
// Release the PCM buffer.
78+
pcm_buf.release();
79+
}
80+
}

0 commit comments

Comments
 (0)