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 1 commit
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
Prev Previous commit
Next Next commit
FullDuplex changed + added example
  • Loading branch information
PilnyTomas committed Oct 11, 2021
commit 79144922e00518e45cfb09a2598333e662633b6f
Empty file.
57 changes: 57 additions & 0 deletions libraries/I2S/examples/FullDuplex/FullDuplex.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
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;

void setup() {
disableCore0WDT();
Serial.begin(115200);
I2S.setAllPins(5, 25, 35, 26);
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
}
}
uint8_t *buffer;
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()*(bps/8));
I2S.write(buffer, I2S.getBufferSize()*(bps/8));
}
53 changes: 7 additions & 46 deletions libraries/I2S/src/I2S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,41 +68,6 @@ I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, u
}
}

I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t inSdPin, uint8_t outSdPin, uint8_t sckPin, uint8_t fsPin) : // set duplex
_deviceIndex(deviceIndex),
_sdPin(inSdPin), // shared data pin
_inSdPin(inSdPin), // input data pin
_outSdPin(outSdPin), // output data pin
_sckPin(sckPin), // clock pin
_fsPin(fsPin), // frame (word) select pin

_state(I2S_STATE_DUPLEX),
_bitsPerSample(0),
_sampleRate(0),
_mode(I2S_PHILIPS_MODE),

_buffer_byte_size(0),

_initialized(false),
_callbackTaskHandle(NULL),
_i2sEventQueue(NULL),
_task_kill_cmd_semaphore_handle(NULL),
_i2s_general_mutex(NULL),
_input_ring_buffer(NULL),
_output_ring_buffer(NULL),
_i2s_dma_buffer_size(1024),
_driveClock(true),
_nesting_counter(0),

_onTransmit(NULL),
_onReceive(NULL)
{
_i2s_general_mutex = xSemaphoreCreateMutex();
if(_i2s_general_mutex == NULL){
log_e("I2S could not create internal mutex!");
}
}

int I2SClass::_createCallbackTask(){
int stack_size = 10000;
if(_callbackTaskHandle == NULL){
Expand Down Expand Up @@ -196,16 +161,15 @@ int I2SClass::_installDriver(){
.use_apll = false
};
// Install and start i2s driver
// TODO solve possible infinite loop
while(ESP_OK != esp_i2s::i2s_driver_install((esp_i2s::i2s_port_t) _deviceIndex, &i2s_config, _I2S_EVENT_QUEUE_LENGTH, &_i2sEventQueue)){
// double buffer size
// increase buffer size
if(2*_i2s_dma_buffer_size <= 1024){
log_w("WARNING i2s driver install failed; Trying to increase I2S DMA buffer size from %d to %d\n", _i2s_dma_buffer_size, 2*_i2s_dma_buffer_size);
setBufferSize(2*_i2s_dma_buffer_size);
}else if(_i2s_dma_buffer_size < 1024){
log_w("WARNING i2s driver install failed; Trying to decrease I2S DMA buffer size from %d to 1024\n", _i2s_dma_buffer_size);
setBufferSize(1024);
}else{
}else{ // install failed with max buffer size
log_e("ERROR i2s driver install failed");
return 0; // ERR
}
Expand Down Expand Up @@ -661,19 +625,18 @@ size_t I2SClass::write(const uint8_t *buffer, size_t size){
}

// blocking version of write
// TODO add timeout
size_t I2SClass::write_blocking(const void *buffer, size_t size){
_take_if_not_holding();
if(_initialized){
if (_state != I2S_STATE_TRANSMITTER && _state != I2S_STATE_DUPLEX) {
if (_state != I2S_STATE_TRANSMITTER && _state != I2S_STATE_DUPLEX){
if(!_enableTransmitter()){
_give_if_top_call();
return 0; // There was an error switching to transmitter
} // _enableTransmitter succeeded ?
} // _state ?
// TODO add timeout
while(availableForWrite() < size){
yield();
uint8_t timeout = 10; // RTOS tics
while(availableForWrite() < size && timeout--){
vTaskDelay(1);
}
if(_output_ring_buffer != NULL){
if(pdTRUE == xRingbufferSend(_output_ring_buffer, buffer, size, 10)){
Expand Down Expand Up @@ -900,9 +863,8 @@ void I2SClass::_onTransferComplete(){
xQueueAddToSet(_task_kill_cmd_semaphore_handle, xQueueSet);

while(true){
//xActivatedMember = xQueueSelectFromSet(xQueueSet, portMAX_DELAY); // default
//xActivatedMember = xQueueSelectFromSet(xQueueSet, portMAX_DELAY); // default - member was never selected even when present
xActivatedMember = xQueueSelectFromSet(xQueueSet, 1); // hack
// TODO try just queue receive at the timeout
if(xActivatedMember == _task_kill_cmd_semaphore_handle){
xSemaphoreTake(_task_kill_cmd_semaphore_handle, 0);
break; // from the infinite loop
Expand Down Expand Up @@ -1103,7 +1065,6 @@ int I2SClass::gpioToAdcChannel(gpio_num_t gpio_num, esp_i2s::adc_channel_t* adc_

#if I2S_INTERFACES_COUNT > 0
I2SClass I2S(I2S_DEVICE, I2S_CLOCK_GENERATOR, PIN_I2S_SD, PIN_I2S_SCK, PIN_I2S_FS); // default - half duplex
//I2SClass I2S(I2S_DEVICE, I2S_CLOCK_GENERATOR, PIN_I2S_SD, PIN_I2S_SD_OUT, PIN_I2S_SCK, PIN_I2S_FS); // full duplex
#endif

#if I2S_INTERFACES_COUNT > 1
Expand Down
6 changes: 2 additions & 4 deletions libraries/I2S/src/I2S.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace esp_i2s {
#endif

#ifndef PIN_I2S_SD
#define PIN_I2S_SD 35 // Input if used in duplex
#define PIN_I2S_SD 35 // Pin 35 is only input!
#endif

#ifndef PIN_I2S_SD_OUT
Expand All @@ -60,7 +60,6 @@ class I2SClass : public Stream
public:
// the device index and pins must map to the "COM" pads in Table 6-1 of the datasheet
I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin);
I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t inSdPin, uint8_t outSdPin, uint8_t sckPin, uint8_t fsPin); // set duplex
// the SCK and FS pins are driven as outputs using the sample rate
int begin(int mode, int sampleRate, int bitsPerSample);
// the SCK and FS pins are inputs, other side controls sample rate
Expand Down Expand Up @@ -153,8 +152,7 @@ class I2SClass : public Stream

i2s_state_t _state;
int _bitsPerSample;
uint32_t _sampleRate; //
//int _sampleRate;
uint32_t _sampleRate;
int _mode;

uint16_t _buffer_byte_size;
Expand Down