Skip to content

[FEATURE] Basic implementation of Arduino's I2S library #5304

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 107 commits into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
185b7ef
[FEATURE] Basic implementation of Arduino's I2S library
PilnyTomas Jun 18, 2021
2aabfb7
[MAINTENANCE] Added I2S to CMakeLists
PilnyTomas Jun 18, 2021
ca6f456
[MAINTENANCE] Joined task blocking (i2s event queue + kill command)
PilnyTomas Jun 18, 2021
32043fc
Merge branch 'espressif:master' into arduino_i2s
PilnyTomas Jun 18, 2021
a3309d4
[FEATURE] Added functions to set pins for both Input and Output
PilnyTomas Jun 21, 2021
3ad6d36
[FEATURE] Added new example demonstrating usage of callbacks
PilnyTomas Jun 24, 2021
12d926f
[MAINTENANCE] Minor changes
PilnyTomas Jun 28, 2021
d7eb3f3
[BACKUP] Work in progress on overlaying buffer (crashing)
PilnyTomas Jul 7, 2021
ad2c540
[BUGFIX] Fixed data type which was causing crashes
PilnyTomas Jul 7, 2021
baff65d
[BUGFIX] Fixed usage of new buffer in read function
PilnyTomas Jul 8, 2021
f366160
[BACKUP] Latest experiments with internal buffer
PilnyTomas Jul 23, 2021
370dd9f
Merge branch 'master' into arduino_i2s
PilnyTomas Jul 28, 2021
7a64d97
[BUGFIX] Fixed merging error in CMakeLists
PilnyTomas Jul 28, 2021
ee969b8
Improved quality of playback
PilnyTomas Jul 30, 2021
5b65b5d
Reimplemented input buffer as ring buffer
PilnyTomas Aug 3, 2021
f0ebf2b
Fixed kill semaphore error; added pin getters/setters
PilnyTomas Aug 5, 2021
a86a32b
Returning accidentally removed mutex give
PilnyTomas Aug 5, 2021
97102fe
Increased DMA buffer size for better performance
PilnyTomas Aug 5, 2021
83bb448
Split begin; changed pin setups and duplex/simplex setup
PilnyTomas Aug 13, 2021
5bb5090
Initial implementation of PDM support (untested)
PilnyTomas Aug 18, 2021
1073b60
Merge branch 'master' into arduino_i2s
PilnyTomas Aug 18, 2021
fbfe7c7
Added esp-dsp in CMakeLists.txt to compile in IDF
PilnyTomas Aug 20, 2021
9cb2d3d
Pre-release changes
PilnyTomas Sep 1, 2021
3bdb4e5
Extended SimpleTone example with DAC settings
PilnyTomas Sep 2, 2021
8c8d357
Removed ArduinoSound from CMakeLists
PilnyTomas Sep 2, 2021
adb66dc
[FEATURE] Basic implementation of Arduino's I2S library
PilnyTomas Jun 18, 2021
4577331
[MAINTENANCE] Added I2S to CMakeLists
PilnyTomas Jun 18, 2021
13a988c
[MAINTENANCE] Joined task blocking (i2s event queue + kill command)
PilnyTomas Jun 18, 2021
019490c
[FEATURE] Added functions to set pins for both Input and Output
PilnyTomas Jun 21, 2021
b18cb31
[FEATURE] Added new example demonstrating usage of callbacks
PilnyTomas Jun 24, 2021
d5a66dd
[MAINTENANCE] Minor changes
PilnyTomas Jun 28, 2021
64a3bb2
[BACKUP] Work in progress on overlaying buffer (crashing)
PilnyTomas Jul 7, 2021
992c80a
[BUGFIX] Fixed data type which was causing crashes
PilnyTomas Jul 7, 2021
64bd076
[BUGFIX] Fixed usage of new buffer in read function
PilnyTomas Jul 8, 2021
635dc5a
[BACKUP] Latest experiments with internal buffer
PilnyTomas Jul 23, 2021
d84057b
Improved quality of playback
PilnyTomas Jul 30, 2021
7da54b8
Reimplemented input buffer as ring buffer
PilnyTomas Aug 3, 2021
d5a3a05
Fixed kill semaphore error; added pin getters/setters
PilnyTomas Aug 5, 2021
f95fdb6
Returning accidentally removed mutex give
PilnyTomas Aug 5, 2021
8d99a4d
Increased DMA buffer size for better performance
PilnyTomas Aug 5, 2021
8519d67
Split begin; changed pin setups and duplex/simplex setup
PilnyTomas Aug 13, 2021
b0d45ce
Initial implementation of PDM support (untested)
PilnyTomas Aug 18, 2021
f45e5ba
Added esp-dsp in CMakeLists.txt to compile in IDF
PilnyTomas Aug 20, 2021
cb6da04
Pre-release changes
PilnyTomas Sep 1, 2021
cdf3a7c
Extended SimpleTone example with DAC settings
PilnyTomas Sep 2, 2021
991f54c
Removed ArduinoSound from CMakeLists
PilnyTomas Sep 2, 2021
2270f4c
Merging CMakeLists
PilnyTomas Sep 2, 2021
9fd0042
ESP32-S2 support
PilnyTomas Sep 2, 2021
7b77310
Removed excessive I2S from CMakeLists
PilnyTomas Sep 3, 2021
b3fdeec
Variable pin for ADC
PilnyTomas Sep 20, 2021
cde002f
Fixed data types for sample_rate inconsistent with IDF i2s driver
PilnyTomas Sep 21, 2021
14e2c7f
Fixed #ifdef to #if
PilnyTomas Sep 21, 2021
2645cf4
Fixed forgotten #ifdef to #if
PilnyTomas Sep 21, 2021
545d916
Merge branch 'master' into arduino_i2s
SuGlider Sep 21, 2021
80f49da
Updated Keywords
PilnyTomas Sep 22, 2021
139aef3
GPIO to ADC conversion methods wrapped in ADC support #if
PilnyTomas Sep 22, 2021
1d481e9
Added .skip.esp32c3 files untill C3 is supported
PilnyTomas Sep 22, 2021
ca0887b
All private functions have now underscore preceeding their name
PilnyTomas Sep 22, 2021
2dfab5f
Proposed wrapping functions for thread safety
PilnyTomas Sep 22, 2021
83d5094
Small fix: Added new function as class member
PilnyTomas Sep 23, 2021
28e6947
Applied nesting locks to all public functions
PilnyTomas Sep 23, 2021
a8727ad
Added aditional checks
PilnyTomas Sep 29, 2021
b1e1387
Added thread safety example
PilnyTomas Sep 30, 2021
39372eb
Thread safety example: Added 2 tasks to use more public functions
PilnyTomas Sep 30, 2021
23e65bd
Mono channel support
PilnyTomas Oct 8, 2021
7914492
FullDuplex changed + added example
PilnyTomas Oct 11, 2021
a65dad7
Merge branch 'master' into arduino_i2s
PilnyTomas Oct 13, 2021
f61e30d
Minor changes to FullDuplex example
PilnyTomas Oct 13, 2021
ba155a5
Added support for 8 bps
PilnyTomas Oct 13, 2021
4bc2633
Moved driver install before ringbuffer init
PilnyTomas Oct 13, 2021
ea037b1
BugFix - return was called before mutex release in read
PilnyTomas Oct 13, 2021
0b66402
Changed #if constants for PDM and ADC/DAC
PilnyTomas Oct 14, 2021
660656f
BugFix: forgotten init flag rise for PDM mode during init + #if const…
PilnyTomas Oct 14, 2021
9da5942
bugfix: Changes on the i2s_set_clk and DMA size
pedrominatel Oct 21, 2021
ef1a825
bugfix: Reverted the DMA buffer and fix on the i2s_set_clk for Philli…
pedrominatel Oct 22, 2021
a56be41
Split PDM modes to mono and stereo + renamed ADC mode
PilnyTomas Oct 25, 2021
3f9458c
Modified internal initialization flags and checks
PilnyTomas Oct 25, 2021
d7f6f6e
Merge branch 'master' into arduino_i2s
PilnyTomas Oct 26, 2021
5e4c7a4
Merge branch 'master' into arduino_i2s
PilnyTomas Nov 16, 2021
0e9d34e
Single-sample writes are now blocking (same as Arduino)
PilnyTomas Nov 19, 2021
0e478b9
removed kill sempahore for callback task deletion
PilnyTomas Nov 19, 2021
4cc4e26
added few more checks
PilnyTomas Nov 19, 2021
3dfa490
Removed Callback locks
PilnyTomas Nov 22, 2021
35ec3e4
Implemented peek
PilnyTomas Nov 22, 2021
90232a9
Merge branch 'master' into arduino_i2s
PilnyTomas Nov 22, 2021
5d786e7
Bugfix - check if task exists before deleteing
PilnyTomas Nov 23, 2021
39bfd11
Added draft for unit tests
PilnyTomas Nov 25, 2021
8af5b2a
Merge branch 'arduino_i2s' of github.com:PilnyTomas/arduino-esp32 int…
PilnyTomas Nov 25, 2021
262b18e
Basic UART comm for unit tests
PilnyTomas Nov 26, 2021
0afe17c
Work In Progress on I2S data transfer
PilnyTomas Dec 2, 2021
cd2c8c8
Work In Progress on data fix function
PilnyTomas Dec 8, 2021
395fb08
Fixed WDT
PilnyTomas Jan 4, 2022
6420fad
Removed unsupported examples and unit tests
PilnyTomas Jan 6, 2022
cedff7d
Initial code polish
PilnyTomas Jan 6, 2022
a73a1a6
fixes buffer size - no noise now
SuGlider Jan 6, 2022
29b05a3
Fix free bug for 24 and 32 bps; add warning to unsupported modes
PilnyTomas Jan 6, 2022
5b98d71
Merge branch 'master' into arduino_i2s
PilnyTomas Jan 6, 2022
e1dc00e
Initial documentation of I2S lib
PilnyTomas Jan 18, 2022
e883358
Modifications to I2S doc
PilnyTomas Jan 19, 2022
d02f392
Updates and small fixes - slave mode, pins,...
PilnyTomas Jan 19, 2022
459ed79
Structure review and syntax fixes
pedrominatel Feb 1, 2022
28d6871
Merge branch 'master' into arduino_i2s
pedrominatel Feb 1, 2022
6591f5b
Fix replace() failing (#6224)
s-hadinger Feb 3, 2022
1046f59
Upload to the component registry (#6203)
magicarm22 Feb 3, 2022
bb4d902
add feather esp32 v2 and qtpy c3 board def (#6223)
ladyada Feb 3, 2022
9b066ea
Added dual antenna for WiFi (based on the ESP32-WROOM-DA module) (#6226)
pedrominatel Feb 3, 2022
5a13725
Merge branch 'espressif:master' into arduino_i2s
PilnyTomas Feb 4, 2022
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
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ set(LIBRARY_SRCS
libraries/HTTPClient/src/HTTPClient.cpp
libraries/HTTPUpdate/src/HTTPUpdate.cpp
libraries/LittleFS/src/LittleFS.cpp
libraries/I2S/src/I2S.cpp
libraries/NetBIOS/src/NetBIOS.cpp
libraries/Preferences/src/Preferences.cpp
libraries/RainMaker/src/RMaker.cpp
Expand Down Expand Up @@ -161,7 +162,6 @@ set(BLE_SRCS
libraries/BLE/src/GeneralUtils.cpp
)


set(includedirs
variants/${IDF_TARGET}/
cores/esp32/
Expand All @@ -178,6 +178,7 @@ set(includedirs
libraries/HTTPClient/src
libraries/HTTPUpdate/src
libraries/LittleFS/src
libraries/I2S/src
libraries/NetBIOS/src
libraries/Preferences/src
libraries/RainMaker/src
Expand Down Expand Up @@ -233,6 +234,8 @@ function(maybe_add_component component_name)
endif()
endfunction()

maybe_add_component(esp-dsp)

if(IDF_TARGET MATCHES "esp32" AND CONFIG_ESP_RMAKER_TASK_STACK)
maybe_add_component(esp_rainmaker)
maybe_add_component(qrcode)
Expand Down
Empty file.
86 changes: 86 additions & 0 deletions libraries/I2S/examples/ADCPlotter/ADCPlotter.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
This example is only for ESP devices.

This example demonstrates usage of integrated Digital to Analog Converter (DAC)
You can display sound wave from audio device, or just measure voltage.

To display audio prepare circuit found in following link or drafted as ASCII art
https://forum.arduino.cc/index.php?topic=567581.0
(!) Note that unlike in the link we are connecting the supply line to 3.3V (not 5V)
because ADC can measure only up to around 3V. Anything above 3V will be very inaccurate.

^ +3.3V
|
_
| |10k
|_|
| | |10uF
GPIO34-------------*------------| |----------- line in
(Default ADC pin) | +| |
|
_
| |10k
|_|
|
|
V GND

Connect hot wire of your audio to Line in and GNd wire of audio cable to common ground (GND)

Second option to measure voltage on trimmer / potentiometer has following connection
^ +3.3V
|
_
| |
GPIO34----------->| |
(Default ADC pin) |_|
|
|
_
| | optional resistor
|_|
|
|
V GND
Optional resistor will decrease read value.

Steps to run:
1. Select target board:
Tools -> Board -> ESP32 Arduino -> your board
2. Upload sketch
Press upload button (arrow in top left corner)
When you see in console line like this: "Connecting........_____.....__"
On your board press and hold Boot button and press EN button shortly. Now you can release both buttons.
You should see lines like this: "Writing at 0x00010000... (12 %)" with rising percentage on each line.
If this fails, try the board buttons right after pressing upload button, or reconnect the USB cable.
3. Open plotter
Tools -> Serial Plotter
Enjoy

Created by Tomas Pilny
on 17th June 2021
*/

#include <I2S.h>

void setup() {
// Open serial communications and wait for port to open:
// A baud rate of 115200 is used instead of 9600 for a faster data rate
// on non-native USB ports
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// start I2S at 8 kHz with 32-bits per sample
if (!I2S.begin(ADC_DAC_MODE, 8000, 16)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
}
}

void loop() {
// read a sample
int sample = I2S.read();
Serial.println(sample);
}
Empty file.
59 changes: 59 additions & 0 deletions libraries/I2S/examples/FullDuplex/FullDuplex.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
This example is only for ESP
This example demonstrates simultaneous usage of microphone and speaker using single I2S module.
The application transfers data from input to output

Circuit:
* ESP32
* GND connected GND
* VIN connected 5V
* SCK 5
* FS 25
* DIN 35
* DOUT 26
* I2S microphone
* I2S decoder + headphones / speaker

created 8 October 2021
by Tomas Pilny
*/

#include <I2S.h>
const long sampleRate = 16000;
const int bitsPerSample = 32;
uint8_t *buffer;

void setup() {
Serial.begin(115200);
//I2S.setAllPins(5, 25, 35, 26); // you can change default pins; order of pins = (CLK, WS, IN, OUT)
if(!I2S.setDuplex()){
Serial.println("ERROR - could not set duplex");
while(true){
vTaskDelay(10); // Cannot continue
}
}
if (!I2S.begin(I2S_PHILIPS_MODE, sampleRate, bitsPerSample)) {
Serial.println("Failed to initialize I2S!");
while(true){
vTaskDelay(10); // Cannot continue
}
}
buffer = (uint8_t*) malloc(I2S.getBufferSize() * (bitsPerSample / 8));
if(buffer == NULL){
Serial.println("Failed to allocate buffer!");
while(true){
vTaskDelay(10); // Cannot continue
}
}
Serial.println("Setup done");
}

void loop() {
//I2S.write(I2S.read()); // primitive implementation sample-by-sample

// Buffer based implementation
I2S.read(buffer, I2S.getBufferSize() * (bitsPerSample / 8));
I2S.write(buffer, I2S.getBufferSize() * (bitsPerSample / 8));

//optimistic_yield(1000); // yield if last yield occurred before <parameter> CPU clock cycles ago
}
Empty file.
44 changes: 44 additions & 0 deletions libraries/I2S/examples/InputSerialPlotter/InputSerialPlotter.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
This example reads audio data from an Invensense's ICS43432 I2S microphone
breakout board, and prints out the samples to the Serial console. The
Serial Plotter built into the Arduino IDE can be used to plot the audio
data (Tools -> Serial Plotter)

Circuit:
* Arduino/Genuino Zero, MKR family and Nano 33 IoT
* ICS43432:
* GND connected GND
* 3.3V connected to 3.3V (Zero, Nano, ESP32), VCC (MKR)
* WS connected to pin 0 (Zero) or 3 (MKR), A2 (Nano) or 25 (ESP32)
* CLK connected to pin 1 (Zero) or 2 (MKR), A3 (Nano) or 5 (ESP32)
* SD connected to pin 9 (Zero) or A6 (MKR), 4 (Nano) or 26 (ESP32)
created 17 November 2016
by Sandeep Mistry
*/

#include <I2S.h>

void setup() {
// Open serial communications and wait for port to open:
// A baud rate of 115200 is used instead of 9600 for a faster data rate
// on non-native USB ports
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// start I2S at 8 kHz with 32-bits per sample
if (!I2S.begin(I2S_PHILIPS_MODE, 8000, 32)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
}
}

void loop() {
// read a sample
int sample = I2S.read();

if (sample && sample != -1 && sample != 1) {
Serial.println(sample);
}
}
Empty file.
79 changes: 79 additions & 0 deletions libraries/I2S/examples/SimpleTone/SimpleTone.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
This example generates a square wave based tone at a specified frequency
and sample rate. Then outputs the data using the I2S interface to a
MAX08357 I2S Amp Breakout board.

I2S Circuit:
* Arduino/Genuino Zero, MKR family and Nano 33 IoT
* MAX08357:
* GND connected GND
* VIN connected 5V
* LRC connected to pin 0 (Zero) or 3 (MKR), A2 (Nano) or 25 (ESP32)
* BCLK connected to pin 1 (Zero) or 2 (MKR), A3 (Nano) or 5 (ESP32)
* DIN connected to pin 9 (Zero) or A6 (MKR), 4 (Nano) or 26 (ESP32)

DAC Circuit:
* ESP32 or ESP32-S2
* Audio amplifier
- Note:
- ESP32 has DAC on GPIO pins 25 and 26.
- ESP32-S2 has DAC on GPIO pins 17 and 18.
- Connect speaker(s) or headphones.

created 17 November 2016
by Sandeep Mistry
For ESP extended
Tomas Pilny
2nd September 2021
*/

#include <I2S.h>
const int frequency = 440; // frequency of square wave in Hz
const int amplitude = 500; // amplitude of square wave
const int sampleRate = 8000; // sample rate in Hz
const int bps = 16;

const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave

short sample = amplitude; // current sample value
int count = 0;

i2s_mode_t mode = I2S_PHILIPS_MODE; // I2S decoder is needed
// i2s_mode_t mode = ADC_DAC_MODE; // Audio amplifier is needed

// Mono channel input
// This is ESP specific implementation -
// samples will be automatically copied to both channels inside I2S driver
// If you want to have true mono output use I2S_PHILIPS_MODE and interlay
// second channel with 0-value samples.
// The order of channels is RIGH followed by LEFT
//i2s_mode_t mode = I2S_RIGHT_JUSTIFIED_MODE; // I2S decoder is needed

void setup() {
Serial.begin(115200);
Serial.println("I2S simple tone");

// start I2S at the sample rate with 16-bits per sample
if (!I2S.begin(mode, sampleRate, bps)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
}
}

void loop() {
if (count % halfWavelength == 0 ) {
// invert the sample every half wavelength count multiple to generate square wave
sample = -1 * sample;
}

if(mode == I2S_PHILIPS_MODE || mode == ADC_DAC_MODE){ // write the same sample twice, once for Right and once for Left channel
I2S.write(sample); // Right channel
I2S.write(sample); // Left channel
}else if(mode == I2S_RIGHT_JUSTIFIED_MODE || mode == I2S_LEFT_JUSTIFIED_MODE){
// write the same only once - it will be automatically copied to the other channel
I2S.write(sample);
}

// increment the counter for the next sample
count++;
}
61 changes: 61 additions & 0 deletions libraries/I2S/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#######################################
# Syntax Coloring Map I2S
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

I2S KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################
I2SClass KEYWORD2
begin KEYWORD2
end KEYWORD2

onReceive KEYWORD2
onTransmit KEYWORD2

setSckPin KEYWORD2
setFsPin KEYWORD2
setDataInPin KEYWORD2
setDataOutPin KEYWORD2
setAllPins KEYWORD2

getSckPin KEYWORD2
getFsPin KEYWORD2
getDataPin KEYWORD2
getDataInPin KEYWORD2
getDataOutPin KEYWORD2

setDuplex KEYWORD2
setSimplex KEYWORD2
isDuplex KEYWORD2

setBufferSize KEYWORD2
getBufferSize KEYWORD2

write KEYWORD2
availableForWrite KEYWORD2

read KEYWORD2
available KEYWORD2

gpioToAdcUnit KEYWORD2
gpioToAdcChannel KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
I2S_PHILIPS_MODE LITERAL1
I2S_RIGHT_JUSTIFIED_MODE LITERAL1
I2S_LEFT_JUSTIFIED_MODE LITERAL1
I2S_ADC_DAC LITERAL1
I2S_PDM LITERAL1

PIN_I2S_SCK LITERAL1
PIN_I2S_FS LITERAL1
PIN_I2S_SD LITERAL1
PIN_I2S_SD_OUT LITERAL1
9 changes: 9 additions & 0 deletions libraries/I2S/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=I2S
version=1.0
author=Tomas Pilny
maintainer=Tomas Pilny <[email protected]>
sentence=Enables the communication with devices that use the Inter-IC Sound (I2S) Bus. Specific implementation for ESP.
paragraph=
category=Communication
url=http://www.arduino.cc/en/Reference/I2S
architectures=esp32
Loading