21
21
#include " I2S.h"
22
22
#include " freertos/semphr.h"
23
23
24
-
25
24
#define _I2S_EVENT_QUEUE_LENGTH 16
26
25
#define _I2S_DMA_BUFFER_COUNT 4 // BUFFER COUNT must be between 2 and 128
27
26
#define I2S_INTERFACES_COUNT SOC_I2S_NUM
@@ -94,7 +93,7 @@ I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t inSdPin,
94
93
95
94
int I2SClass::createCallbackTask ()
96
95
{
97
- int stack_size = 15000 ;
96
+ int stack_size = 10000 ;
98
97
if (_callbackTaskHandle == NULL ){
99
98
if (_task_kill_cmd_semaphore_handle == NULL ){
100
99
_task_kill_cmd_semaphore_handle = xSemaphoreCreateBinary ();
@@ -129,9 +128,7 @@ void I2SClass::destroyCallbackTask()
129
128
}
130
129
vSemaphoreDelete (_task_kill_cmd_semaphore_handle); // delete semaphore after usage
131
130
_task_kill_cmd_semaphore_handle = NULL ; // prevent usage of uninitialized (deleted) semaphore
132
- }else { // callback handle check
133
- log_e (" Could not destroy callback" );
134
- }
131
+ } // callback handle check
135
132
}
136
133
137
134
int I2SClass::_installDriver (){
@@ -187,17 +184,19 @@ int I2SClass::_installDriver(){
187
184
.dma_buf_count = _I2S_DMA_BUFFER_COUNT,
188
185
.dma_buf_len = _i2s_dma_buffer_size
189
186
};
190
-
191
- if (ESP_OK != esp_i2s::i2s_driver_install ((esp_i2s::i2s_port_t ) _deviceIndex, &i2s_config, _I2S_EVENT_QUEUE_LENGTH, &_i2sEventQueue)){ // Install and start i2s driver
192
- log_e (" ERROR could not install i2s driver" );
193
- return 0 ; // ERR
194
- }
195
- if (_i2sEventQueue == NULL ){
196
- log_e (" ERROR i2s driver did not create event queue" );
197
- // return 0; // ERR
198
- }else {
199
- log_d (" DEBUG MSG i2s event queue exists" );
200
- }
187
+ // Install and start i2s driver
188
+ while (ESP_OK != esp_i2s::i2s_driver_install ((esp_i2s::i2s_port_t ) _deviceIndex, &i2s_config, _I2S_EVENT_QUEUE_LENGTH, &_i2sEventQueue)){
189
+ // double buffer size
190
+ 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);
191
+ if (2 *_i2s_dma_buffer_size <= 1024 ){
192
+ setBufferSize (2 *_i2s_dma_buffer_size);
193
+ }else if (_i2s_dma_buffer_size < 1024 ){
194
+ setBufferSize (1024 );
195
+ }else {
196
+ log_e (" ERROR i2s driver install failed" );
197
+ return 0 ; // ERR
198
+ }
199
+ } // try installing with increasing size
201
200
202
201
if (_mode == I2S_ADC_DAC){
203
202
esp_i2s::adc_unit_t adc_unit = (esp_i2s::adc_unit_t ) 1 ;
@@ -224,7 +223,7 @@ int I2SClass::_installDriver(){
224
223
return 1 ; // OK
225
224
}
226
225
227
- int I2SClass::begin (int mode, long sampleRate, int bitsPerSample)
226
+ int I2SClass::begin (int mode, int sampleRate, int bitsPerSample)
228
227
{
229
228
// master mode (driving clock and frame select pins - output)
230
229
return begin (mode, sampleRate, bitsPerSample, true );
@@ -233,14 +232,14 @@ int I2SClass::begin(int mode, long sampleRate, int bitsPerSample)
233
232
int I2SClass::begin (int mode, int bitsPerSample)
234
233
{
235
234
log_e (" ERROR I2SClass::begin Audio in Slave mode is not implemented for ESP\n \
236
- Note: If it is NOT your intention to initialize in slave mode, you are probably missing <sampleRate> parameter - see the declaration below\
235
+ Note: If it is NOT your intention to initialize in slave mode, you are probably missing <sampleRate> parameter - see the declaration below\n \
237
236
\t int I2SClass::begin(int mode, long sampleRate, int bitsPerSample)" );
238
237
return 0 ; // ERR
239
238
// slave mode (not driving clock and frame select pin - input)
240
239
// return begin(mode, 0, bitsPerSample, false);
241
240
}
242
241
243
- int I2SClass::begin (int mode, long sampleRate, int bitsPerSample, bool driveClock)
242
+ int I2SClass::begin (int mode, int sampleRate, int bitsPerSample, bool driveClock)
244
243
{
245
244
if (_initialized){
246
245
end ();
@@ -279,10 +278,12 @@ int I2SClass::begin(int mode, long sampleRate, int bitsPerSample, bool driveCloc
279
278
}
280
279
281
280
if (!_installDriver ()){
281
+ _initialized = false ;
282
282
return 0 ; // ERR
283
283
}
284
284
285
285
if (!createCallbackTask ()){
286
+ _initialized = false ;
286
287
return 0 ; // ERR
287
288
}
288
289
@@ -389,21 +390,11 @@ int I2SClass::setAllPins(int sckPin, int fsPin, int inSdPin, int outSdPin){
389
390
}
390
391
391
392
int I2SClass::setDuplex (){
392
- /*
393
- if(_inSdPin < 0 || _outSdPin < 0){
394
- log_e("I2S cannot set Duplex - one or both pins not set\n input pin = %d\toutput pin = %d", _inSdPin, _outSdPin);
395
- return 0; // ERR
396
- }
397
- */
398
393
_state = I2S_STATE_DUPLEX;
399
394
return 1 ;
400
395
}
401
396
402
397
int I2SClass::setSimplex (){
403
- if (_sdPin < 0 ){
404
- log_e (" I2S cannot set Simplex - shared data pin is not set\n data pin = %d" , _sdPin);
405
- return 0 ; // ERR
406
- }
407
398
_state = I2S_STATE_IDLE;
408
399
return 1 ;
409
400
}
@@ -432,9 +423,15 @@ int I2SClass::getDataOutPin(){
432
423
return _outSdPin;
433
424
}
434
425
435
- int I2SClass::_uninstallDriver (){
436
- // TODO
437
- return 1 ; // Ok
426
+ void I2SClass::_uninstallDriver (){
427
+ if (_mode == I2S_ADC_DAC){
428
+ esp_i2s::i2s_adc_disable ((esp_i2s::i2s_port_t ) _deviceIndex);
429
+ }
430
+ esp_i2s::i2s_driver_uninstall ((esp_i2s::i2s_port_t ) _deviceIndex);
431
+
432
+ if (_state != I2S_STATE_DUPLEX){
433
+ _state = I2S_STATE_IDLE;
434
+ }
438
435
}
439
436
440
437
void I2SClass::end ()
@@ -443,15 +440,8 @@ void I2SClass::end()
443
440
destroyCallbackTask ();
444
441
445
442
if (_initialized){
446
-
447
- if (_mode == I2S_ADC_DAC){
448
- esp_i2s::i2s_adc_disable ((esp_i2s::i2s_port_t ) _deviceIndex);
449
- }
450
- esp_i2s::i2s_driver_uninstall ((esp_i2s::i2s_port_t ) _deviceIndex);
443
+ _uninstallDriver ();
451
444
_initialized = false ;
452
- if (_state != I2S_STATE_DUPLEX){
453
- _state = I2S_STATE_IDLE;
454
- }
455
445
}
456
446
_onTransmit = NULL ;
457
447
_onReceive = NULL ;
@@ -538,20 +528,49 @@ size_t I2SClass::write(const uint8_t *buffer, size_t size)
538
528
return write ((const void *)buffer, size);
539
529
}
540
530
541
- size_t I2SClass::write (const void *buffer, size_t size)
531
+ // blocking version of write
532
+ // TODO add timeout
533
+ size_t I2SClass::write_blocking (const void *buffer, size_t size)
534
+ {
535
+ if (_state != I2S_STATE_TRANSMITTER && _state != I2S_STATE_DUPLEX) {
536
+ if (!enableTransmitter ()){
537
+ return 0 ; // There was an error switching to transmitter
538
+ }
539
+ }
540
+ // TODO add timeout
541
+ while (availableForWrite () < size){
542
+ yield ();
543
+ }
544
+ if (pdTRUE == xRingbufferSend (_output_ring_buffer, buffer, size, 10 )){
545
+ return size;
546
+ }else {
547
+ return 0 ;
548
+ }
549
+ }
550
+
551
+ // non-blocking version of write
552
+ size_t I2SClass::write_nonblocking (const void *buffer, size_t size)
542
553
{
543
554
if (_state != I2S_STATE_TRANSMITTER && _state != I2S_STATE_DUPLEX) {
544
555
if (!enableTransmitter ()){
545
556
return 0 ; // There was an error switching to transmitter
546
557
}
547
558
}
559
+ if (availableForWrite () < size){
560
+ flush ();
561
+ }
548
562
if (pdTRUE == xRingbufferSend (_output_ring_buffer, buffer, size, 10 )){
549
563
return size;
550
564
}else {
551
565
return 0 ;
552
566
}
553
567
}
554
568
569
+ size_t I2SClass::write (const void *buffer, size_t size){
570
+ // return write_blocking(buffer, size);
571
+ return write_nonblocking (buffer, size);
572
+ }
573
+
555
574
int I2SClass::peek ()
556
575
{
557
576
// TODO
@@ -596,10 +615,9 @@ int I2SClass::setBufferSize(int bufferSize)
596
615
if (bufferSize >= 8 && bufferSize <= 1024 ){
597
616
_i2s_dma_buffer_size = bufferSize;
598
617
if (_initialized){
599
- end ();
600
- return begin (_mode, _sampleRate, _bitsPerSample, _driveClock );
618
+ _uninstallDriver ();
619
+ return _installDriver ( );
601
620
}
602
-
603
621
return 1 ; // OK
604
622
}else {
605
623
return 0 ; // ERR
@@ -628,84 +646,101 @@ int I2SClass::enableReceiver()
628
646
return 1 ; // Ok
629
647
}
630
648
649
+ void I2SClass::_tx_done_routine (uint8_t * prev_item){
650
+ static bool prev_item_valid = false ;
651
+ const size_t single_dma_buf = _i2s_dma_buffer_size*(_bitsPerSample/8 );
652
+ static size_t item_size = 0 ;
653
+ static size_t prev_item_size = 0 ;
654
+ static void *item = NULL ;
655
+ static int prev_item_offset = 0 ;
656
+ static size_t bytes_written;
657
+
658
+ if (prev_item_valid){ // use item from previous round
659
+ esp_i2s::i2s_write ((esp_i2s::i2s_port_t ) _deviceIndex, prev_item+prev_item_offset, prev_item_size, &bytes_written, 0 );
660
+ if (prev_item_size == bytes_written){
661
+ prev_item_valid = false ;
662
+ } // write size check
663
+ prev_item_offset = bytes_written;
664
+ prev_item_size -= bytes_written;
665
+ } // prev_item_valid
666
+
667
+ if (_buffer_byte_size - xRingbufferGetCurFreeSize (_output_ring_buffer) >= single_dma_buf){ // fill up the I2S DMA buffer
668
+ bytes_written = 0 ;
669
+ item_size = 0 ;
670
+ // if(_buffer_byte_size - xRingbufferGetCurFreeSize(_output_ring_buffer) >= _i2s_dma_buffer_size*(_bitsPerSample/8)){ // don't read from almost empty buffer
671
+ item = xRingbufferReceiveUpTo (_output_ring_buffer, &item_size, pdMS_TO_TICKS (1000 ), single_dma_buf);
672
+ if (item != NULL ){
673
+ esp_i2s::i2s_write ((esp_i2s::i2s_port_t ) _deviceIndex, item, item_size, &bytes_written, 0 );
674
+ if (item_size != bytes_written){ // save item that was not written correctly for later
675
+ memcpy (prev_item, (void *)&((uint8_t *)item)[bytes_written], item_size-bytes_written);
676
+ prev_item_size = item_size - bytes_written;
677
+ prev_item_offset = 0 ;
678
+ prev_item_valid = true ;
679
+ } // save item that was not written correctly for later
680
+ vRingbufferReturnItem (_output_ring_buffer, item);
681
+ } // Check received item
682
+ } // don't read from almost empty buffer
683
+
684
+ if (_onTransmit){
685
+ _onTransmit ();
686
+ } // user callback
687
+ }
688
+
689
+ void I2SClass::_rx_done_routine (){
690
+ static size_t bytes_read;
691
+ const size_t single_dma_buf = _i2s_dma_buffer_size*(_bitsPerSample/8 );
692
+ uint8_t *_inputBuffer = (uint8_t *)malloc (_i2s_dma_buffer_size*4 );
693
+
694
+ size_t avail = xRingbufferGetCurFreeSize (_input_ring_buffer);
695
+ esp_i2s::i2s_read ((esp_i2s::i2s_port_t ) _deviceIndex, _inputBuffer, avail <= single_dma_buf ? avail : single_dma_buf, (size_t *) &bytes_read, 0 );
696
+ if (pdTRUE != xRingbufferSend (_input_ring_buffer, _inputBuffer, bytes_read, 0 )){
697
+ log_w (" I2S failed to send item from DMA to internal buffer\n " );
698
+ }else {
699
+ if (_onReceive) {
700
+ _onReceive ();
701
+ } // user callback
702
+ } // xRingbufferSendComplete
703
+ free (_inputBuffer);
704
+ }
705
+
706
+
631
707
void I2SClass::onTransferComplete ()
632
708
{
709
+ uint8_t prev_item[_i2s_dma_buffer_size*4 ];
633
710
static QueueSetHandle_t xQueueSet;
634
- const size_t single_dma_buf = _i2s_dma_buffer_size*(_bitsPerSample/8 );
635
711
QueueSetMemberHandle_t xActivatedMember;
636
- esp_i2s::i2s_event_type_t i2s_event;
637
- size_t item_size = 0 ;
638
- size_t prev_item_size = 0 ;
639
- void *item = NULL ;
640
- bool prev_item_valid = false ;
641
- size_t bytes_written, bytes_read;
642
- int prev_item_offset = 0 ;
643
- uint8_t prev_item[_i2s_dma_buffer_size*4 ];
644
- uint8_t _inputBuffer[_i2s_dma_buffer_size*4 ];
645
-
712
+ esp_i2s::i2s_event_t i2s_event;
646
713
xQueueSet = xQueueCreateSet (sizeof (i2s_event)*_I2S_EVENT_QUEUE_LENGTH + 1 );
647
714
configASSERT (xQueueSet);
648
715
configASSERT (_i2sEventQueue);
649
716
xQueueAddToSet (_i2sEventQueue, xQueueSet);
650
717
xQueueAddToSet (_task_kill_cmd_semaphore_handle, xQueueSet);
651
718
652
719
while (true ){
653
- xActivatedMember = xQueueSelectFromSet (xQueueSet, portMAX_DELAY);
720
+ // xActivatedMember = xQueueSelectFromSet(xQueueSet, portMAX_DELAY); // defaul
721
+ xActivatedMember = xQueueSelectFromSet (xQueueSet, 5 ); // hack
722
+ // TODO try just queue receive at the timeout
654
723
if (xActivatedMember == _task_kill_cmd_semaphore_handle){
655
724
xSemaphoreTake (_task_kill_cmd_semaphore_handle, 0 );
656
725
break ; // from the infinite loop
657
- }else if (xActivatedMember == _i2sEventQueue){
658
- xQueueReceive (_i2sEventQueue, &i2s_event, 0 );
659
- if (i2s_event == esp_i2s::I2S_EVENT_TX_DONE){
660
- if (prev_item_valid){ // use item from previous round
661
- esp_i2s::i2s_write ((esp_i2s::i2s_port_t ) _deviceIndex, prev_item+prev_item_offset, prev_item_size, &bytes_written, 0 );
662
- if (prev_item_size == bytes_written){
663
- prev_item_valid = false ;
664
- } // write size check
665
- prev_item_offset = bytes_written;
666
- prev_item_size -= bytes_written;
667
- } // prev_item_valid
668
-
669
- if (_buffer_byte_size - xRingbufferGetCurFreeSize (_output_ring_buffer) >= single_dma_buf){ // fill up the I2S DMA buffer
670
-
671
- bytes_written = 0 ;
672
- item_size = 0 ;
673
- item = xRingbufferReceiveUpTo (_output_ring_buffer, &item_size, pdMS_TO_TICKS (1000 ), single_dma_buf);
674
- if (item != NULL ){
675
- esp_i2s::i2s_write ((esp_i2s::i2s_port_t ) _deviceIndex, item, item_size, &bytes_written, 0 );
676
- if (item_size != bytes_written){ // save item that was not written correctly for later
677
- memcpy (prev_item, (void *)&((uint8_t *)item)[bytes_written], item_size-bytes_written);
678
- prev_item_size = item_size - bytes_written;
679
- prev_item_offset = 0 ;
680
- prev_item_valid = true ;
681
- } // save item that was not written correctly for later
682
- vRingbufferReturnItem (_output_ring_buffer, item);
683
- } // Check received item
684
- } // don't read from almost empty buffer
685
-
686
- if (_onTransmit){
687
- _onTransmit ();
688
- } // user callback
689
-
690
- }else if (i2s_event == esp_i2s::I2S_EVENT_RX_DONE){
691
- size_t avail = xRingbufferGetCurFreeSize (_input_ring_buffer);
692
- esp_i2s::i2s_read ((esp_i2s::i2s_port_t ) _deviceIndex, _inputBuffer, avail <= single_dma_buf ? avail : single_dma_buf, (size_t *) &bytes_read, 0 );
693
- if (pdTRUE != xRingbufferSend (_input_ring_buffer, _inputBuffer, bytes_read, 0 )){
694
- log_w (" I2S failed to send item from DMA to internal buffer\n " );
695
- }else {
696
- if (_onReceive) {
697
- _onReceive ();
698
- } // user callback
699
- } // xRingbufferSendComplete
700
- } // RX Done
701
- } // Queue set (I2S event or kill command)
726
+ // }else if(xActivatedMember == _i2sEventQueue){ // default
727
+ }else if (xActivatedMember == _i2sEventQueue || xActivatedMember == NULL ){ // hack
728
+ if (uxQueueMessagesWaiting (_i2sEventQueue)){
729
+ xQueueReceive (_i2sEventQueue, &i2s_event, 0 );
730
+ if (i2s_event.type == esp_i2s::I2S_EVENT_TX_DONE){
731
+ _tx_done_routine (prev_item);
732
+ }else if (i2s_event.type == esp_i2s::I2S_EVENT_RX_DONE){
733
+ _rx_done_routine ();
734
+ } // RX Done
735
+ } // queue not empty
736
+ }else {
737
+ }
702
738
} // infinite loop
703
739
_callbackTaskHandle = NULL ; // prevent secondary termination to non-existing task
704
740
}
705
741
706
742
void I2SClass::onDmaTransferComplete (void *)
707
743
{
708
-
709
744
I2S.onTransferComplete ();
710
745
vTaskDelete (NULL );
711
746
}
0 commit comments