2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// you may not use this file except in compliance with the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You may obtain a copy of the License at
  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//     http://www.apache.org/licenses/LICENSE-2.0
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Unless required by applicable law or agreed to in writing, software
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See the License for the specific language governing permissions and
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// limitations under the License.
  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <string.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <stdbool.h> 
  
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <math.h> 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <esp_types.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "freertos/FreeRTOS.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "freertos/queue.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "freertos/xtensa_api.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-03-02 12:07:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "freertos/semphr.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "esp32/rom/lldesc.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "driver/gpio.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "driver/i2s.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "driver/dac.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-03-02 12:07:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "hal/i2s_hal.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:19:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "adc1_private.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 16:30:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "esp_intr_alloc.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "esp_err.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-03-02 12:07:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "esp_attr.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "esp_log.h" 
  
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "esp_pm.h" 
  
						 
					
						
							
								
									
										
										
										
											2019-11-21 18:40:46 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "esp_efuse.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char *  I2S_TAG  =  " I2S " ;  
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define I2S_CHECK(a, str, ret) if (!(a)) {                                              \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG , " %s:%d (%s):%s " ,  __FILE__ ,  __LINE__ ,  __FUNCTION__ ,  str ) ;        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ( ret ) ;                                                                    \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define I2S_ENTER_CRITICAL_ISR()          portENTER_CRITICAL_ISR(&i2s_spinlock[i2s_num]) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define I2S_EXIT_CRITICAL_ISR()           portEXIT_CRITICAL_ISR(&i2s_spinlock[i2s_num]) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define I2S_ENTER_CRITICAL()              portENTER_CRITICAL(&i2s_spinlock[i2s_num]) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define I2S_EXIT_CRITICAL()               portEXIT_CRITICAL(&i2s_spinlock[i2s_num]) 
  
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define I2S_FULL_DUPLEX_SLAVE_MODE_MASK   (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_SLAVE) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define I2S_FULL_DUPLEX_MASTER_MODE_MASK  (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_MASTER) 
  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ brief  DMA  buffer  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  * * buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  buf_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  * curr_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SemaphoreHandle_t  mux ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    xQueueHandle  queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lldesc_t  * * desc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  i2s_dma_t ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ brief  I2S  object  instance 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_port_t  i2s_num ;          /*!< I2S port number*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  queue_size ;              /*!< I2S event queue size*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QueueHandle_t  i2s_queue ;     /*!< I2S queue handler*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  dma_buf_count ;           /*!< DMA buffer count, number of buffer*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  dma_buf_len ;             /*!< DMA buffer length, length of each buffer*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_dma_t  * rx ;               /*!< DMA Tx buffer*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_dma_t  * tx ;               /*!< DMA Rx buffer*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_isr_handle_t  i2s_isr_handle ;  /*!< I2S Interrupt handle*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  channel_num ;             /*!< Number of channels*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  bytes_per_sample ;         /*!< Bytes per sample*/ 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  bits_per_sample ;         /*!< Bits per sample*/ 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    i2s_mode_t  mode ;             /*!< I2S Working mode*/ 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint32_t  sample_rate ;               /*!< I2S sample rate */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  use_apll ;                /*!< I2S use APLL clock */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-14 14:33:45 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  tx_desc_auto_clear ;     /*!< I2S auto clear tx descriptor on underflow */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  fixed_mclk ;              /*!< I2S fixed MLCK clock */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-19 16:06:20 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    double  real_rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_pm_lock_handle_t  pm_lock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_context_t  hal ;         /*!< I2S hal context*/ 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  i2s_obj_t ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  i2s_obj_t  * p_i2s_obj [ I2S_NUM_MAX ]  =  { 0 } ;  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  portMUX_TYPE  i2s_spinlock [ I2S_NUM_MAX ] ;  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  _i2s_adc_unit  =  - 1 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  _i2s_adc_channel  =  - 1 ;  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  i2s_dma_t  * i2s_create_dma_queue ( i2s_port_t  i2s_num ,  int  dma_buf_count ,  int  dma_buf_len ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  esp_err_t  i2s_destroy_dma_queue ( i2s_port_t  i2s_num ,  i2s_dma_t  * dma ) ;  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  esp_err_t  i2s_reset_fifo ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_reset_fifo ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-09 15:20:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  void  gpio_matrix_out_check ( uint32_t  gpio ,  uint32_t  signal_idx ,  bool  out_inv ,  bool  oen_inv )  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //if pin = -1, do not need to configure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( gpio  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        PIN_FUNC_SELECT ( GPIO_PIN_MUX_REG [ gpio ] ,  PIN_FUNC_GPIO ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        gpio_set_direction ( gpio ,  GPIO_MODE_DEF_OUTPUT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        gpio_matrix_out ( gpio ,  signal_idx ,  out_inv ,  oen_inv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-09 15:20:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  void  gpio_matrix_in_check ( uint32_t  gpio ,  uint32_t  signal_idx ,  bool  inv )  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( gpio  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        PIN_FUNC_SELECT ( GPIO_PIN_MUX_REG [ gpio ] ,  PIN_FUNC_GPIO ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //Set direction, for some GPIOs, the input function are not enabled as default.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gpio_set_direction ( gpio ,  GPIO_MODE_DEF_INPUT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        gpio_matrix_in ( gpio ,  signal_idx ,  inv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_clear_intr_status ( i2s_port_t  i2s_num ,  uint32_t  clr_mask )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_clear_intr_status ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  clr_mask ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_enable_rx_intr ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_enable_rx_intr ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_disable_rx_intr ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_disable_rx_intr ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_disable_tx_intr ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_disable_tx_intr ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_enable_tx_intr ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_enable_tx_intr ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-19 16:06:20 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								float  i2s_get_clk ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  p_i2s_obj [ i2s_num ] - > real_rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 14:14:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  esp_err_t  i2s_isr_register ( i2s_port_t  i2s_num ,  int  intr_alloc_flags ,  void  ( * fn ) ( void * ) ,  void  *  arg ,  i2s_isr_handle_t  * handle )  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  esp_intr_alloc ( i2s_periph_signal [ i2s_num ] . irq ,  intr_alloc_flags ,  fn ,  arg ,  handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  float  i2s_apll_get_fi2s ( int  bits_per_sample ,  int  sdm0 ,  int  sdm1 ,  int  sdm2 ,  int  odir )  
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  f_xtal  =  ( int ) rtc_clk_xtal_freq_get ( )  *  1000000 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 18:40:46 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if CONFIG_IDF_TARGET_ESP32 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /* ESP32 rev0 silicon issue for APLL range/accuracy, please see ESP32 ECO document for more information on this */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( esp_efuse_get_chip_ver ( )  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        sdm0  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        sdm1  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 18:40:46 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  fout  =  f_xtal  *  ( sdm2  +  sdm1  /  256.0f  +  sdm0  /  65536.0f  +  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( fout  <  APLL_MIN_FREQ  | |  fout  >  APLL_MAX_FREQ )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  APLL_MAX_FREQ ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  fpll  =  fout  /  ( 2  *  ( odir + 2 ) ) ;  //== fi2s (N=1, b=0, a=1)
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  fpll / 2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ brief      APLL  calculate  function ,  was  described  by  following : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             APLL  Output  frequency  is  given  by  the  formula : 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *             apll_freq  =  xtal_freq  *  ( 4  +  sdm2  +  sdm1 / 256  +  sdm0 / 65536 ) / ( ( o_div  +  2 )  *  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             apll_freq  =  fout  /  ( ( o_div  +  2 )  *  2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *             The  dividend  in  this  expression  should  be  in  the  range  of  240  -  600  MHz . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             In  rev .  0  of  ESP32 ,  sdm0  and  sdm1  are  unused  and  always  set  to  0. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             *  sdm0   frequency  adjustment  parameter ,  0. .255 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             *  sdm1   frequency  adjustment  parameter ,  0. .255 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             *  sdm2   frequency  adjustment  parameter ,  0. .63 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             *  o_div   frequency  divider ,  0. .31 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             The  most  accurate  way  to  find  the  sdm0 . .2  and  odir  parameters  is  to  loop  through  them  all , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             then  apply  the  above  formula ,  finding  the  closest  frequency  to  the  desired  one . 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *             But  256 * 256 * 64 * 32  =  134.217 .728  loops  are  too  slow  with  ESP32 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             1.  We  will  choose  the  parameters  with  the  highest  level  of  change , 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *                With  350 MHz < fout < 500 MHz ,  we  limit  the  sdm2  from  4  to  9 , 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *                Take  average  frequency  close  to  the  desired  frequency ,  and  select  sdm2 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *             2.  Next ,  we  look  for  sequences  of  less  influential  and  more  detailed  parameters , 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *                also  by  taking  the  average  of  the  largest  and  smallest  frequencies  closer  to  the  desired  frequency . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *             3.  And  finally ,  loop  through  all  the  most  detailed  of  the  parameters ,  finding  the  best  desired  frequency 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param [ in ]   rate                   The  I2S  Frequency  ( MCLK ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param [ in ]   bits_per_sample        The  bits  per  sample 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param [ out ]       sdm0              The  sdm  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param [ out ]       sdm1              The  sdm  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param [ out ]       sdm2              The  sdm  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param [ out ]       odir              The  odir 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ return      ESP_ERR_INVALID_ARG  or  ESP_OK 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  esp_err_t  i2s_apll_calculate_fi2s ( int  rate ,  int  bits_per_sample ,  int  * sdm0 ,  int  * sdm1 ,  int  * sdm2 ,  int  * odir )  
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  _odir ,  _sdm0 ,  _sdm1 ,  _sdm2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  avg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  min_rate ,  max_rate ,  min_diff ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( rate / bits_per_sample / 2 / 8  <  APLL_I2S_MIN_RATE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * sdm0  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * sdm1  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * sdm2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * odir  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    min_diff  =  APLL_MAX_FREQ ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( _sdm2  =  4 ;  _sdm2  <  9 ;  _sdm2  + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        max_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  255 ,  255 ,  _sdm2 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        min_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  0 ,  0 ,  _sdm2 ,  31 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        avg  =  ( max_rate  +  min_rate ) / 2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-18 13:52:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( abs ( avg  -  rate )  <  min_diff )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            min_diff  =  abs ( avg  -  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * sdm2  =  _sdm2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    min_diff  =  APLL_MAX_FREQ ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( _odir  =  0 ;  _odir  <  32 ;  _odir  + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        max_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  255 ,  255 ,  * sdm2 ,  _odir ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        min_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  0 ,  0 ,  * sdm2 ,  _odir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        avg  =  ( max_rate  +  min_rate ) / 2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-18 13:52:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( abs ( avg  -  rate )  <  min_diff )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            min_diff  =  abs ( avg  -  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * odir  =  _odir ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-18 13:52:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    min_diff  =  APLL_MAX_FREQ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( _sdm2  =  4 ;  _sdm2  <  9 ;  _sdm2  + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        max_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  255 ,  255 ,  _sdm2 ,  * odir ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        min_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  0 ,  0 ,  _sdm2 ,  * odir ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        avg  =  ( max_rate  +  min_rate ) / 2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( abs ( avg  -  rate )  <  min_diff )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            min_diff  =  abs ( avg  -  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * sdm2  =  _sdm2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    min_diff  =  APLL_MAX_FREQ ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( _sdm1  =  0 ;  _sdm1  <  256 ;  _sdm1  + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        max_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  255 ,  _sdm1 ,  * sdm2 ,  * odir ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        min_rate  =  i2s_apll_get_fi2s ( bits_per_sample ,  0 ,  _sdm1 ,  * sdm2 ,  * odir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        avg  =  ( max_rate  +  min_rate ) / 2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( abs ( avg  -  rate )  <  min_diff )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            min_diff  =  abs ( avg  -  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * sdm1  =  _sdm1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    min_diff  =  APLL_MAX_FREQ ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( _sdm0  =  0 ;  _sdm0  <  256 ;  _sdm0  + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        avg  =  i2s_apll_get_fi2s ( bits_per_sample ,  _sdm0 ,  * sdm1 ,  * sdm2 ,  * odir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( abs ( avg  -  rate )  <  min_diff )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            min_diff  =  abs ( avg  -  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * sdm0  =  _sdm0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_set_clk ( i2s_port_t  i2s_num ,  uint32_t  rate ,  i2s_bits_per_sample_t  bits ,  i2s_channel_t  ch )  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  factor  =  ( 256 % bits ) ?  384  :  256 ;  // According to hardware codec requirement(supported 256fs or 384fs)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  clkmInteger ,  clkmDecimals ,  bck  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    double  denom  =  ( double ) 1  /  64 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    int  channel  =  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_dma_t  * save_tx  =  NULL ,  * save_rx  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( bits  %  8  ! =  0  | |  bits  >  I2S_BITS_PER_SAMPLE_32BIT  | |  bits  <  I2S_BITS_PER_SAMPLE_16BIT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " Invalid bits per sample " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ]  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " Not initialized yet " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p_i2s_obj [ i2s_num ] - > sample_rate  =  rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    double  clkmdiv  =  ( double ) I2S_BASE_CLK  /  ( rate  *  factor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( clkmdiv  >  256 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " clkmdiv is too large \r \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // wait all on-going writing finish
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  & &  p_i2s_obj [ i2s_num ] - > tx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        xSemaphoreTake ( p_i2s_obj [ i2s_num ] - > tx - > mux ,  ( portTickType ) portMAX_DELAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  & &  p_i2s_obj [ i2s_num ] - > rx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        xSemaphoreTake ( p_i2s_obj [ i2s_num ] - > rx - > mux ,  ( portTickType ) portMAX_DELAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_stop ( i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_set_tx_mode ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  ch ,  bits ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_hal_set_rx_mode ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  ch ,  bits ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 19:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > channel_num  ! =  ch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > channel_num  =  ( ch  = =  2 )  ?  2  :  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( bits  ! =  p_i2s_obj [ i2s_num ] - > bits_per_sample )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > bits_per_sample  =  bits ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > bytes_per_sample  =  p_i2s_obj [ i2s_num ] - > bits_per_sample  /  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Round bytes_per_sample up to next multiple of 16 bits
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  halfwords_per_sample  =  ( p_i2s_obj [ i2s_num ] - > bits_per_sample  +  15 )  /  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > bytes_per_sample  =  halfwords_per_sample  *  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Because limited of DMA buffer is 4092 bytes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > dma_buf_len  *  p_i2s_obj [ i2s_num ] - > bytes_per_sample  *  p_i2s_obj [ i2s_num ] - > channel_num  >  4092 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > dma_buf_len  =  4092  /  p_i2s_obj [ i2s_num ] - > bytes_per_sample  /  p_i2s_obj [ i2s_num ] - > channel_num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Re-create TX DMA buffer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            save_tx  =  p_i2s_obj [ i2s_num ] - > tx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > tx  =  i2s_create_dma_queue ( i2s_num ,  p_i2s_obj [ i2s_num ] - > dma_buf_count ,  p_i2s_obj [ i2s_num ] - > dma_buf_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( p_i2s_obj [ i2s_num ] - > tx  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ESP_LOGE ( I2S_TAG ,  " Failed to create tx dma buffer " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                i2s_driver_uninstall ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  ESP_ERR_NO_MEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            i2s_hal_set_out_link_addr ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  ( uint32_t )  p_i2s_obj [ i2s_num ] - > tx - > desc [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //destroy old tx dma if exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( save_tx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                i2s_destroy_dma_queue ( i2s_num ,  save_tx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Re-create RX DMA buffer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            save_rx  =  p_i2s_obj [ i2s_num ] - > rx ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > rx  =  i2s_create_dma_queue ( i2s_num ,  p_i2s_obj [ i2s_num ] - > dma_buf_count ,  p_i2s_obj [ i2s_num ] - > dma_buf_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( p_i2s_obj [ i2s_num ] - > rx  = =  NULL ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ESP_LOGE ( I2S_TAG ,  " Failed to create rx dma buffer " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                i2s_driver_uninstall ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  ESP_ERR_NO_MEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            i2s_hal_set_in_link ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  p_i2s_obj [ i2s_num ] - > dma_buf_len  *  p_i2s_obj [ i2s_num ] - > channel_num  *  p_i2s_obj [ i2s_num ] - > bytes_per_sample ,  ( uint32_t )  p_i2s_obj [ i2s_num ] - > rx - > desc [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            //destroy old rx dma if exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( save_rx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                i2s_destroy_dma_queue ( i2s_num ,  save_rx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    double  mclk ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  sdm0 ,  sdm1 ,  sdm2 ,  odir ,  m_scale  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  fi2s_clk  =  rate * channel * bits * m_scale ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  ( I2S_MODE_DAC_BUILT_IN  |  I2S_MODE_ADC_BUILT_IN ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //DAC uses bclk as sample clock, not WS. WS can be something arbitrary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //Rate as given to this function is the intended sample rate;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //According to the TRM, WS clk equals to the sample rate, and bclk is double the speed of WS
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        uint32_t  b_clk  =  rate  *  I2S_AD_BCK_FACTOR ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-20 14:57:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        fi2s_clk  / =  I2S_AD_BCK_FACTOR ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        int  factor2  =  60 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mclk  =  b_clk  *  factor2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmdiv  =  ( ( double )  I2S_BASE_CLK )  /  mclk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmInteger  =  clkmdiv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmDecimals  =  ( clkmdiv  -  clkmInteger )  /  denom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bck  =  mclk  /  b_clk ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_PDM 
  
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_PDM )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        uint32_t  b_clk  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            int  fp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            int  fs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_hal_get_tx_pdm ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  & fp ,  & fs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            b_clk  =  rate  *  I2S_PDM_BCK_FACTOR  *  ( fp  /  fs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fi2s_clk  / =  ( I2S_PDM_BCK_FACTOR  *  ( fp  /  fs ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bool  en ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_hal_get_rx_sinc_dsr_16_en ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  & en ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            b_clk  =  rate  *  I2S_PDM_BCK_FACTOR  *  ( en  ?  2  :  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fi2s_clk  / =  ( I2S_PDM_BCK_FACTOR  *  ( en  ?  2  :  1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  factor2  =  5  ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mclk  =  b_clk  *  factor2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmdiv  =  ( ( double )  I2S_BASE_CLK )  /  mclk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmInteger  =  clkmdiv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmDecimals  =  ( clkmdiv  -  clkmInteger )  /  denom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bck  =  mclk  /  b_clk ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        clkmInteger  =  clkmdiv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        clkmDecimals  =  ( clkmdiv  -  clkmInteger )  /  denom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mclk  =  clkmInteger  +  denom  *  clkmDecimals ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bck  =  factor / ( bits  *  channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if ( p_i2s_obj [ i2s_num ] - > use_apll  & &  p_i2s_obj [ i2s_num ] - > fixed_mclk )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fi2s_clk  =  p_i2s_obj [ i2s_num ] - > fixed_mclk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_scale  =  fi2s_clk / bits / rate / channel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if ( p_i2s_obj [ i2s_num ] - > use_apll  & &  i2s_apll_calculate_fi2s ( fi2s_clk ,  bits ,  & sdm0 ,  & sdm1 ,  & sdm2 ,  & odir )  = =  ESP_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGD ( I2S_TAG ,  " sdm0=%d, sdm1=%d, sdm2=%d, odir=%d " ,  sdm0 ,  sdm1 ,  sdm2 ,  odir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        rtc_clk_apll_enable ( 1 ,  sdm0 ,  sdm1 ,  sdm2 ,  odir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_set_clk_div ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  1 ,  1 ,  0 ,  m_scale ,  m_scale ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_hal_set_clock_sel ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  I2S_CLK_APLL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        double  fi2s_rate  =  i2s_apll_get_fi2s ( bits ,  sdm0 ,  sdm1 ,  sdm2 ,  odir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-19 16:06:20 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > real_rate  =  fi2s_rate / bits / channel / m_scale ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ESP_LOGI ( I2S_TAG ,  " APLL: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK_M: %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            rate ,  fi2s_rate / bits / channel / m_scale ,  bits ,  1 ,  m_scale ,  fi2s_rate ,  fi2s_rate / 8 ,  1 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_set_clock_sel ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  I2S_CLK_D2CLK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_hal_set_clk_div ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  clkmInteger ,  63 ,  clkmDecimals ,  bck ,  bck ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        double  real_rate  =  ( double )  ( I2S_BASE_CLK  /  ( bck  *  bits  *  clkmInteger )  /  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-19 16:06:20 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > real_rate  =  real_rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ESP_LOGI ( I2S_TAG ,  " PLL_D2: Req RATE: %d, real rate: %0.3f, BITS: %u, CLKM: %u, BCK: %u, MCLK: %0.3f, SCLK: %f, diva: %d, divb: %d " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            rate ,  real_rate ,  bits ,  clkmInteger ,  bck ,  ( double ) I2S_BASE_CLK  /  mclk ,  real_rate * bits * channel ,  64 ,  clkmDecimals ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_set_tx_bits_mod ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  bits ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_hal_set_rx_bits_mod ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  bits ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // wait all writing on-going finish
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  & &  p_i2s_obj [ i2s_num ] - > tx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        xSemaphoreGive ( p_i2s_obj [ i2s_num ] - > tx - > mux ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  & &  p_i2s_obj [ i2s_num ] - > rx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        xSemaphoreGive ( p_i2s_obj [ i2s_num ] - > rx - > mux ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_start ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  IRAM_ATTR  i2s_intr_handler_default ( void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_obj_t  * p_i2s  =  ( i2s_obj_t * )  arg ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint32_t  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_hal_get_intr_status ( & ( p_i2s - > hal ) ,  & status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if ( status  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //Avoid spurious interrupt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    i2s_event_t  i2s_event ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  dummy ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    portBASE_TYPE  high_priority_task_awoken  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lldesc_t  * finish_desc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ( status  &  I2S_INTR_OUT_DSCR_ERR )  | |  ( status  &  I2S_INTR_IN_DSCR_ERR ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_EARLY_LOGE ( I2S_TAG ,  " dma error, interrupt status: 0x%08x " ,  status ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s - > i2s_queue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_event . type  =  I2S_EVENT_DMA_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( xQueueIsQueueFullFromISR ( p_i2s - > i2s_queue ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                xQueueReceiveFromISR ( p_i2s - > i2s_queue ,  & dummy ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            xQueueSendFromISR ( p_i2s - > i2s_queue ,  ( void  *  ) & i2s_event ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ( status  &  I2S_INTR_OUT_EOF )  & &  p_i2s - > tx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_hal_get_out_eof_des_addr ( & ( p_i2s - > hal ) ,  ( uint32_t  * ) & finish_desc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // All buffers are empty. This means we have an underflow on our hands.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( xQueueIsQueueFullFromISR ( p_i2s - > tx - > queue ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            xQueueReceiveFromISR ( p_i2s - > tx - > queue ,  & dummy ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-14 14:33:45 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // See if tx descriptor needs to be auto cleared:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This will avoid any kind of noise that may get introduced due to transmission
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // of previous data from tx descriptor on I2S line.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( p_i2s - > tx_desc_auto_clear  = =  true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                memset ( ( void  * )  dummy ,  0 ,  p_i2s - > tx - > buf_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        xQueueSendFromISR ( p_i2s - > tx - > queue ,  ( void * ) ( & finish_desc - > buf ) ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s - > i2s_queue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_event . type  =  I2S_EVENT_TX_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( xQueueIsQueueFullFromISR ( p_i2s - > i2s_queue ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                xQueueReceiveFromISR ( p_i2s - > i2s_queue ,  & dummy ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            xQueueSendFromISR ( p_i2s - > i2s_queue ,  ( void  *  ) & i2s_event ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ( status  &  I2S_INTR_IN_SUC_EOF )  & &  p_i2s - > rx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // All buffers are full. This means we have an overflow.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_get_in_eof_des_addr ( & ( p_i2s - > hal ) ,  ( uint32_t  * ) & finish_desc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( xQueueIsQueueFullFromISR ( p_i2s - > rx - > queue ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            xQueueReceiveFromISR ( p_i2s - > rx - > queue ,  & dummy ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        xQueueSendFromISR ( p_i2s - > rx - > queue ,  ( void * ) ( & finish_desc - > buf ) ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s - > i2s_queue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_event . type  =  I2S_EVENT_RX_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( p_i2s - > i2s_queue  & &  xQueueIsQueueFullFromISR ( p_i2s - > i2s_queue ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                xQueueReceiveFromISR ( p_i2s - > i2s_queue ,  & dummy ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            xQueueSendFromISR ( p_i2s - > i2s_queue ,  ( void  *  ) & i2s_event ,  & high_priority_task_awoken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_clear_intr_status ( & ( p_i2s - > hal ) ,  status ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( high_priority_task_awoken  = =  pdTRUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        portYIELD_FROM_ISR ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  esp_err_t  i2s_destroy_dma_queue ( i2s_port_t  i2s_num ,  i2s_dma_t  * dma )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  bux_idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ]  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " Not initialized yet " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dma  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " dma is NULL " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( bux_idx  =  0 ;  bux_idx  <  p_i2s_obj [ i2s_num ] - > dma_buf_count ;  bux_idx + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( dma - > desc  & &  dma - > desc [ bux_idx ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            free ( dma - > desc [ bux_idx ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( dma - > buf  & &  dma - > buf [ bux_idx ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            free ( dma - > buf [ bux_idx ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( dma - > buf )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        free ( dma - > buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dma - > desc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        free ( dma - > desc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    vQueueDelete ( dma - > queue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    vSemaphoreDelete ( dma - > mux ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    free ( dma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  i2s_dma_t  * i2s_create_dma_queue ( i2s_port_t  i2s_num ,  int  dma_buf_count ,  int  dma_buf_len )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  bux_idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  sample_size  =  p_i2s_obj [ i2s_num ] - > bytes_per_sample  *  p_i2s_obj [ i2s_num ] - > channel_num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_dma_t  * dma  =  ( i2s_dma_t * )  malloc ( sizeof ( i2s_dma_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dma  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " Error malloc i2s_dma_t " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    memset ( dma ,  0 ,  sizeof ( i2s_dma_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > buf  =  ( char  * * ) malloc ( sizeof ( char * )  *  dma_buf_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dma - > buf  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " Error malloc dma buffer pointer " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-25 14:14:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        free ( dma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    memset ( dma - > buf ,  0 ,  sizeof ( char * )  *  dma_buf_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( bux_idx  =  0 ;  bux_idx  <  dma_buf_count ;  bux_idx + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-10 18:00:11 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dma - > buf [ bux_idx ]  =  ( char * )  heap_caps_calloc ( 1 ,  dma_buf_len  *  sample_size ,  MALLOC_CAP_DMA ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( dma - > buf [ bux_idx ]  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ESP_LOGE ( I2S_TAG ,  " Error malloc dma buffer " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_destroy_dma_queue ( i2s_num ,  dma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGD ( I2S_TAG ,  " Addr[%d] = %d " ,  bux_idx ,  ( int ) dma - > buf [ bux_idx ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > desc  =  ( lldesc_t * * )  malloc ( sizeof ( lldesc_t * )  *  dma_buf_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dma - > desc  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " Error malloc dma description " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_destroy_dma_queue ( i2s_num ,  dma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( bux_idx  =  0 ;  bux_idx  <  dma_buf_count ;  bux_idx + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-10 18:00:11 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ]  =  ( lldesc_t * )  heap_caps_malloc ( sizeof ( lldesc_t ) ,  MALLOC_CAP_DMA ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( dma - > desc [ bux_idx ]  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ESP_LOGE ( I2S_TAG ,  " Error malloc dma description entry " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_destroy_dma_queue ( i2s_num ,  dma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( bux_idx  =  0 ;  bux_idx  <  dma_buf_count ;  bux_idx + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > owner  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > eof  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > sosf  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > length  =  dma_buf_len  *  sample_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > size  =  dma_buf_len  *  sample_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > buf  =  ( uint8_t  * )  dma - > buf [ bux_idx ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dma - > desc [ bux_idx ] - > empty  =  ( uint32_t ) ( ( bux_idx  <  ( dma_buf_count  -  1 ) )  ?  ( dma - > desc [ bux_idx  +  1 ] )  :  dma - > desc [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > queue  =  xQueueCreate ( dma_buf_count  -  1 ,  sizeof ( char * ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > mux  =  xSemaphoreCreateMutex ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > rw_pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > buf_size  =  dma_buf_len  *  sample_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dma - > curr_ptr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP_LOGI ( I2S_TAG ,  " DMA Malloc info, datalen=blocksize=%d, dma_buf_count=%d " ,  dma_buf_len  *  sample_size ,  dma_buf_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  dma ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_start ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    //start DMA link
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_reset_fifo ( i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_reset ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    esp_intr_disable ( p_i2s_obj [ i2s_num ] - > i2s_isr_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_clear_intr_status ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  I2S_INTR_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_enable_tx_intr ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_start_tx ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_enable_rx_intr ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_start_rx ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_intr_enable ( p_i2s_obj [ i2s_num ] - > i2s_isr_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_stop ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_ENTER_CRITICAL ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_intr_disable ( p_i2s_obj [ i2s_num ] - > i2s_isr_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_stop_tx ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        i2s_disable_tx_intr ( i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_stop_rx ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        i2s_disable_rx_intr ( i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    uint32_t  mask ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_hal_get_intr_status ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  & mask ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_hal_clear_intr_status ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  mask ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    I2S_EXIT_CRITICAL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_set_dac_mode ( i2s_dac_mode_t  dac_mode )  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( dac_mode  <  I2S_DAC_CHANNEL_MAX ) ,  " i2s dac mode error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( dac_mode  = =  I2S_DAC_CHANNEL_DISABLE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dac_output_disable ( DAC_CHANNEL_1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-29 15:31:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dac_output_disable ( DAC_CHANNEL_2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dac_i2s_disable ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dac_i2s_enable ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( dac_mode  &  I2S_DAC_CHANNEL_RIGHT_EN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-09 15:20:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //DAC1, right channel
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dac_output_enable ( DAC_CHANNEL_1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( dac_mode  &  I2S_DAC_CHANNEL_LEFT_EN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-09 15:20:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //DAC2, left channel
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dac_output_enable ( DAC_CHANNEL_2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 16:33:30 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  esp_err_t  _i2s_adc_mode_recover ( void )  
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( ( _i2s_adc_unit  ! =  - 1 )  & &  ( _i2s_adc_channel  ! =  - 1 ) ) ,  " i2s ADC recover error, not initialized... " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  adc_i2s_mode_init ( _i2s_adc_unit ,  _i2s_adc_channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_set_adc_mode ( adc_unit_t  adc_unit ,  adc1_channel_t  adc_channel )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( adc_unit  <  ADC_UNIT_2 ) ,  " i2s ADC unit error, only support ADC1 for now " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // For now, we only support SAR ADC1.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    _i2s_adc_unit  =  adc_unit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    _i2s_adc_channel  =  adc_channel ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  adc_i2s_mode_init ( adc_unit ,  adc_channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_set_pin ( i2s_port_t  i2s_num ,  const  i2s_pin_config_t  * pin )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( pin  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  i2s_set_dac_mode ( I2S_DAC_CHANNEL_BOTH_EN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( pin - > bck_io_num  ! =  - 1  & &  ! GPIO_IS_VALID_GPIO ( pin - > bck_io_num ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " bck_io_num error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( pin - > ws_io_num  ! =  - 1  & &  ! GPIO_IS_VALID_GPIO ( pin - > ws_io_num ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " ws_io_num error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-17 13:12:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( pin - > data_out_num  ! =  - 1  & &  ! GPIO_IS_VALID_OUTPUT_GPIO ( pin - > data_out_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " data_out_num error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( pin - > data_in_num  ! =  - 1  & &  ! GPIO_IS_VALID_GPIO ( pin - > data_in_num ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " data_in_num error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ESP_FAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  bck_sig  =  - 1 ,  ws_sig  =  - 1 ,  data_out_sig  =  - 1 ,  data_in_sig  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    //Each IIS hw module has a RX and TX unit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //For TX unit, the output signal index should be I2SnO_xxx_OUT_IDX
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //For TX unit, the input signal index should be I2SnO_xxx_IN_IDX
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_MASTER )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bck_sig  =  i2s_periph_signal [ i2s_num ] . o_bck_out_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ws_sig  =  i2s_periph_signal [ i2s_num ] . o_ws_out_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_out_sig  =  i2s_periph_signal [ i2s_num ] . o_data_out_sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_SLAVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bck_sig  =  i2s_periph_signal [ i2s_num ] . o_bck_in_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ws_sig  =  i2s_periph_signal [ i2s_num ] . o_ws_in_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_out_sig  =  i2s_periph_signal [ i2s_num ] . o_data_out_sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    //For RX unit, the output signal index should be I2SnI_xxx_OUT_IDX
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //For RX unit, the input signal index shuld be I2SnI_xxx_IN_IDX
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_MASTER )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bck_sig  =  i2s_periph_signal [ i2s_num ] . i_bck_out_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ws_sig  =  i2s_periph_signal [ i2s_num ] . i_ws_out_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_in_sig  =  i2s_periph_signal [ i2s_num ] . i_data_in_sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_SLAVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bck_sig  =  i2s_periph_signal [ i2s_num ] . i_bck_in_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ws_sig  =  i2s_periph_signal [ i2s_num ] . i_ws_in_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            data_in_sig  =  i2s_periph_signal [ i2s_num ] . i_data_in_sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //For "full-duplex + slave" mode, we should select RX signal index for ws and bck.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //For "full-duplex + master" mode, we should select TX signal index for ws and bck.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_FULL_DUPLEX_SLAVE_MODE_MASK )  = =  I2S_FULL_DUPLEX_SLAVE_MODE_MASK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bck_sig  =  i2s_periph_signal [ i2s_num ] . i_bck_in_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ws_sig  =  i2s_periph_signal [ i2s_num ] . i_ws_in_sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_FULL_DUPLEX_MASTER_MODE_MASK )  = =  I2S_FULL_DUPLEX_MASTER_MODE_MASK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bck_sig  =  i2s_periph_signal [ i2s_num ] . o_bck_out_sig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ws_sig  =  i2s_periph_signal [ i2s_num ] . o_ws_out_sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    gpio_matrix_out_check ( pin - > data_out_num ,  data_out_sig ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    gpio_matrix_in_check ( pin - > data_in_num ,  data_in_sig ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_MASTER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gpio_matrix_out_check ( pin - > ws_io_num ,  ws_sig ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gpio_matrix_out_check ( pin - > bck_io_num ,  bck_sig ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_SLAVE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gpio_matrix_in_check ( pin - > ws_io_num ,  ws_sig ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        gpio_matrix_in_check ( pin - > bck_io_num ,  bck_sig ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ESP_LOGD ( I2S_TAG ,  " data: out %d, in: %d, ws: %d, bck: %d " ,  data_out_sig ,  data_in_sig ,  ws_sig ,  bck_sig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_set_sample_rates ( i2s_port_t  i2s_num ,  uint32_t  rate )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ] - > bytes_per_sample  >  0 ) ,  " bits_per_sample not set " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  i2s_set_clk ( i2s_num ,  rate ,  p_i2s_obj [ i2s_num ] - > bits_per_sample ,  p_i2s_obj [ i2s_num ] - > channel_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_PDM 
  
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_set_pdm_rx_down_sample ( i2s_port_t  i2s_num ,  i2s_pdm_dsr_t  dsr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_set_pdm_rx_down_sample ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  dsr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  i2s_set_clk ( i2s_num ,  p_i2s_obj [ i2s_num ] - > sample_rate ,  p_i2s_obj [ i2s_num ] - > bits_per_sample ,  p_i2s_obj [ i2s_num ] - > channel_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2018-11-27 14:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  esp_err_t  i2s_param_config ( i2s_port_t  i2s_num ,  const  i2s_config_t  * i2s_config )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_config ) ,  " param null " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ! ( ( i2s_config - > mode  &  I2S_MODE_ADC_BUILT_IN )  & &  ( i2s_num  ! =  I2S_NUM_0 ) ) ,  " I2S ADC built-in only support on I2S0 " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ! ( ( i2s_config - > mode  &  I2S_MODE_DAC_BUILT_IN )  & &  ( i2s_num  ! =  I2S_NUM_0 ) ) ,  " I2S DAC built-in only support on I2S0 " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2019-12-09 15:20:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( ( i2s_config - > communication_format  &  I2S_COMM_FORMAT_I2S )  | |  ( i2s_config - > communication_format  &  I2S_COMM_FORMAT_PCM ) ) ,  " I2S communication format invalid. " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_PDM 
  
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ! ( ( i2s_config - > mode  &  I2S_MODE_PDM )  & &  ( i2s_num  ! =  I2S_NUM_0 ) ) ,  " I2S DAC PDM only support on I2S0 " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    periph_module_enable ( i2s_periph_signal [ i2s_num ] . module ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-03 18:55:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if ( i2s_config - > mode  &  I2S_MODE_ADC_BUILT_IN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //in ADC built-in mode, we need to call i2s_set_adc_mode to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //initialize the specific ADC channel.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //in the current stage, we only support ADC1 and single channel mode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //In default data mode, the ADC data is in 12-bit resolution mode.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        adc_power_always_on ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    // configure I2S data port interface.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_reset_fifo ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_config_param ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  i2s_config ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  & &   ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        i2s_hal_enable_sig_loopback ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_MASTER )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            i2s_hal_enable_master_mode ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            i2s_hal_enable_slave_mode ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    p_i2s_obj [ i2s_num ] - > use_apll  =  i2s_config - > use_apll ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-14 14:33:45 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p_i2s_obj [ i2s_num ] - > tx_desc_auto_clear  =  i2s_config - > tx_desc_auto_clear ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 13:50:45 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    p_i2s_obj [ i2s_num ] - > fixed_mclk  =  i2s_config - > fixed_mclk ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_zero_dma_buffer ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > rx  & &  p_i2s_obj [ i2s_num ] - > rx - > buf  ! =  NULL  & &  p_i2s_obj [ i2s_num ] - > rx - > buf_size  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( int  i  =  0 ;  i  <  p_i2s_obj [ i2s_num ] - > dma_buf_count ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            memset ( p_i2s_obj [ i2s_num ] - > rx - > buf [ i ] ,  0 ,  p_i2s_obj [ i2s_num ] - > rx - > buf_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > tx  & &  p_i2s_obj [ i2s_num ] - > tx - > buf  ! =  NULL  & &  p_i2s_obj [ i2s_num ] - > tx - > buf_size  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        int  bytes_left  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bytes_left  =  ( p_i2s_obj [ i2s_num ] - > tx - > buf_size  -  p_i2s_obj [ i2s_num ] - > tx - > rw_pos )  %  4 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( bytes_left )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            size_t  zero_bytes  =  0 ,  bytes_written ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_write ( i2s_num ,  ( void  * ) & zero_bytes ,  bytes_left ,  & bytes_written ,  portMAX_DELAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( int  i  =  0 ;  i  <  p_i2s_obj [ i2s_num ] - > dma_buf_count ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            memset ( p_i2s_obj [ i2s_num ] - > tx - > buf [ i ] ,  0 ,  p_i2s_obj [ i2s_num ] - > tx - > buf_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_driver_install ( i2s_port_t  i2s_num ,  const  i2s_config_t  * i2s_config ,  int  queue_size ,  void *  i2s_queue )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    esp_err_t  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_config  ! =  NULL ) ,  " I2S configuration must not NULL " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_config - > dma_buf_count  > =  2  & &  i2s_config - > dma_buf_count  < =  128 ) ,  " I2S buffer count less than 128 and more than 2 " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_config - > dma_buf_len  > =  8  & &  i2s_config - > dma_buf_len  < =  1024 ) ,  " I2S buffer length at most 1024 and more than 8 " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ]  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ]  =  ( i2s_obj_t * )  malloc ( sizeof ( i2s_obj_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ]  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ESP_LOGE ( I2S_TAG ,  " Malloc I2S driver error " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  ESP_ERR_NO_MEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        memset ( p_i2s_obj [ i2s_num ] ,  0 ,  sizeof ( i2s_obj_t ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-15 14:44:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        portMUX_TYPE  i2s_spinlock_unlocked [ 1 ]  =  { portMUX_INITIALIZER_UNLOCKED } ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( int  x  =  0 ;  x  <  I2S_NUM_MAX ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_spinlock [ x ]  =  i2s_spinlock_unlocked [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //To make sure hardware is enabled before any hardware register operations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        periph_module_enable ( i2s_periph_signal [ i2s_num ] . module ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_hal_init ( & ( p_i2s_obj [ i2s_num ] - > hal ) ,  i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > i2s_num  =  i2s_num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > dma_buf_count  =  i2s_config - > dma_buf_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > dma_buf_len  =  i2s_config - > dma_buf_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > i2s_queue  =  i2s_queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > mode  =  i2s_config - > mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > bits_per_sample  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > bytes_per_sample  =  0 ;  // Not initialized yet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > channel_num  =  i2s_config - > channel_format  <  I2S_CHANNEL_FMT_ONLY_RIGHT  ?  2  :  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
									
										
										
										
											2019-02-22 19:48:59 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( i2s_config - > use_apll )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        err  =  esp_pm_lock_create ( ESP_PM_NO_LIGHT_SLEEP ,  0 ,  " i2s_driver " ,  & p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        err  =  esp_pm_lock_create ( ESP_PM_APB_FREQ_MAX ,  0 ,  " i2s_driver " ,  & p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( err  ! =  ESP_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 19:48:59 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        free ( p_i2s_obj [ i2s_num ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ]  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG ,  " I2S pm lock error " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif  //CONFIG_PM_ENABLE
  
						 
					
						
							
								
									
										
										
										
											2019-02-22 19:48:59 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //initial interrupt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        err  =  i2s_isr_register ( i2s_num ,  i2s_config - > intr_alloc_flags ,  i2s_intr_handler_default ,  p_i2s_obj [ i2s_num ] ,  & p_i2s_obj [ i2s_num ] - > i2s_isr_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( err  ! =  ESP_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( p_i2s_obj [ i2s_num ] - > pm_lock )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                esp_pm_lock_delete ( p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            free ( p_i2s_obj [ i2s_num ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-07 14:32:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ]  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            ESP_LOGE ( I2S_TAG ,  " Register I2S Interrupt error " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-07 14:32:32 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_stop ( i2s_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-23 23:12:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        err  =  i2s_param_config ( i2s_num ,  i2s_config ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( err  ! =  ESP_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            i2s_driver_uninstall ( i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ESP_LOGE ( I2S_TAG ,  " I2S param configure error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( i2s_queue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > i2s_queue  =  xQueueCreate ( queue_size ,  sizeof ( i2s_event_t ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * ( ( QueueHandle_t * )  i2s_queue )  =  p_i2s_obj [ i2s_num ] - > i2s_queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ESP_LOGI ( I2S_TAG ,  " queue free spaces: %d " ,  uxQueueSpacesAvailable ( p_i2s_obj [ i2s_num ] - > i2s_queue ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > i2s_queue  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        //set clock and start
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  i2s_set_clk ( i2s_num ,  i2s_config - > sample_rate ,  i2s_config - > bits_per_sample ,  p_i2s_obj [ i2s_num ] - > channel_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ESP_LOGW ( I2S_TAG ,  " I2S driver already installed " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_driver_uninstall ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-06 13:11:11 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ]  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ESP_LOGI ( I2S_TAG ,  " already uninstalled " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_stop ( i2s_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_intr_free ( p_i2s_obj [ i2s_num ] - > i2s_isr_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > tx  ! =  NULL  & &  p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_TX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_destroy_dma_queue ( i2s_num ,  p_i2s_obj [ i2s_num ] - > tx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > tx  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > rx  ! =  NULL  & &  p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_RX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        i2s_destroy_dma_queue ( i2s_num ,  p_i2s_obj [ i2s_num ] - > rx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > rx  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > i2s_queue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        vQueueDelete ( p_i2s_obj [ i2s_num ] - > i2s_queue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > i2s_queue  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if ( p_i2s_obj [ i2s_num ] - > use_apll )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rtc_clk_apll_enable ( 0 ,  0 ,  0 ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( p_i2s_obj [ i2s_num ] - > pm_lock )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 19:48:59 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        esp_pm_lock_delete ( p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-08-16 16:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    free ( p_i2s_obj [ i2s_num ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    p_i2s_obj [ i2s_num ]  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    periph_module_disable ( i2s_periph_signal [ i2s_num ] . module ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_write ( i2s_port_t  i2s_num ,  const  void  * src ,  size_t  size ,  size_t  * bytes_written ,  TickType_t  ticks_to_wait )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  * data_ptr ,  * src_byte ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  bytes_can_write ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * bytes_written  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( size  <  I2S_MAX_BUFFER_SIZE ) ,  " size is too large " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ] - > tx ) ,  " tx NULL " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    xSemaphoreTake ( p_i2s_obj [ i2s_num ] - > tx - > mux ,  ( portTickType ) portMAX_DELAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_pm_lock_acquire ( p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    src_byte  =  ( char  * ) src ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    while  ( size  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > tx - > rw_pos  = =  p_i2s_obj [ i2s_num ] - > tx - > buf_size  | |  p_i2s_obj [ i2s_num ] - > tx - > curr_ptr  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( xQueueReceive ( p_i2s_obj [ i2s_num ] - > tx - > queue ,  & p_i2s_obj [ i2s_num ] - > tx - > curr_ptr ,  ticks_to_wait )  = =  pdFALSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > tx - > rw_pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGD ( I2S_TAG ,  " size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %d " ,  size ,  p_i2s_obj [ i2s_num ] - > tx - > rw_pos ,  p_i2s_obj [ i2s_num ] - > tx - > buf_size ,  ( int ) p_i2s_obj [ i2s_num ] - > tx - > curr_ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data_ptr  =  ( char * ) p_i2s_obj [ i2s_num ] - > tx - > curr_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data_ptr  + =  p_i2s_obj [ i2s_num ] - > tx - > rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bytes_can_write  =  p_i2s_obj [ i2s_num ] - > tx - > buf_size  -  p_i2s_obj [ i2s_num ] - > tx - > rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( bytes_can_write  >  size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bytes_can_write  =  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        memcpy ( data_ptr ,  src_byte ,  bytes_can_write ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        size  - =  bytes_can_write ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        src_byte  + =  bytes_can_write ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > tx - > rw_pos  + =  bytes_can_write ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ( * bytes_written )  + =  bytes_can_write ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_pm_lock_release ( p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    xSemaphoreGive ( p_i2s_obj [ i2s_num ] - > tx - > mux ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if SOC_I2S_SUPPORTS_ADC_DAC 
  
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_adc_enable ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ]  ! =  NULL ) ,  " Not initialized yet " ,  ESP_ERR_INVALID_STATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_ADC_BUILT_IN ) ,  " i2s built-in adc not enabled " ,  ESP_ERR_INVALID_STATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-25 22:19:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    adc1_dma_mode_acquire ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    _i2s_adc_mode_recover ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-20 14:57:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_start_rx ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i2s_hal_reset ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  i2s_set_clk ( i2s_num ,  p_i2s_obj [ i2s_num ] - > sample_rate ,  p_i2s_obj [ i2s_num ] - > bits_per_sample ,  p_i2s_obj [ i2s_num ] - > channel_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								esp_err_t  i2s_adc_disable ( i2s_port_t  i2s_num )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ]  ! =  NULL ) ,  " Not initialized yet " ,  ESP_ERR_INVALID_STATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ] - > mode  &  I2S_MODE_ADC_BUILT_IN ) ,  " i2s built-in adc not enabled " ,  ESP_ERR_INVALID_STATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-20 14:57:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    i2s_hal_stop_rx ( & ( p_i2s_obj [ i2s_num ] - > hal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    adc1_lock_release ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-02-20 16:00:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-12-08 20:07:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_write_expand ( i2s_port_t  i2s_num ,  const  void  * src ,  size_t  size ,  size_t  src_bits ,  size_t  aim_bits ,  size_t  * bytes_written ,  TickType_t  ticks_to_wait )  
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  * data_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  bytes_can_write ,  tail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  src_bytes ,  aim_bytes ,  zero_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * bytes_written  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( size  >  0 ) ,  " size must greater than zero " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( aim_bits  *  size  <  I2S_MAX_BUFFER_SIZE ) ,  " size is too large " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( aim_bits  > =  src_bits ) ,  " aim_bits mustn't be less than src_bits " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ] - > tx ) ,  " tx NULL " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( src_bits  <  I2S_BITS_PER_SAMPLE_8BIT  | |  aim_bits  <  I2S_BITS_PER_SAMPLE_8BIT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG , " bits mustn't be less than 8, src_bits %d aim_bits %d " ,  src_bits ,  aim_bits ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( src_bits  >  I2S_BITS_PER_SAMPLE_32BIT  | |  aim_bits  >  I2S_BITS_PER_SAMPLE_32BIT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-06 17:00:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG , " bits mustn't be greater than 32, src_bits %d aim_bits %d " ,  src_bits ,  aim_bits ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ( src_bits  = =  I2S_BITS_PER_SAMPLE_16BIT  | |  src_bits  = =  I2S_BITS_PER_SAMPLE_32BIT )  & &  ( size  %  2  ! =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG , " size must be a even number while src_bits is even, src_bits %d size %d " ,  src_bits ,  size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( src_bits  = =  I2S_BITS_PER_SAMPLE_24BIT  & &  ( size  %  3  ! =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ESP_LOGE ( I2S_TAG , " size must be a multiple of 3 while src_bits is 24, size %d " ,  size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ESP_ERR_INVALID_ARG ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    src_bytes  =  src_bits  /  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    aim_bytes  =  aim_bits  /  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    zero_bytes  =  aim_bytes  -  src_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    xSemaphoreTake ( p_i2s_obj [ i2s_num ] - > tx - > mux ,  ( portTickType ) portMAX_DELAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size  =  size  *  aim_bytes  /  src_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ESP_LOGD ( I2S_TAG , " aim_bytes %d src_bytes %d size %d " ,  aim_bytes ,  src_bytes ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( size  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > tx - > rw_pos  = =  p_i2s_obj [ i2s_num ] - > tx - > buf_size  | |  p_i2s_obj [ i2s_num ] - > tx - > curr_ptr  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( xQueueReceive ( p_i2s_obj [ i2s_num ] - > tx - > queue ,  & p_i2s_obj [ i2s_num ] - > tx - > curr_ptr ,  ticks_to_wait )  = =  pdFALSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > tx - > rw_pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data_ptr  =  ( char * ) p_i2s_obj [ i2s_num ] - > tx - > curr_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data_ptr  + =  p_i2s_obj [ i2s_num ] - > tx - > rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bytes_can_write  =  p_i2s_obj [ i2s_num ] - > tx - > buf_size  -  p_i2s_obj [ i2s_num ] - > tx - > rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( bytes_can_write  >  size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bytes_can_write  =  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tail  =  bytes_can_write  %  aim_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bytes_can_write  =  bytes_can_write  -  tail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        memset ( data_ptr ,  0 ,  bytes_can_write ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( int  j  =  0 ;  j  <  bytes_can_write ;  j  + =  ( aim_bytes  -  zero_bytes ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            j  + =  zero_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            memcpy ( & data_ptr [ j ] ,  ( const  char  * ) ( src  +  * bytes_written ) ,  aim_bytes  -  zero_bytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( * bytes_written )  + =  ( aim_bytes  -  zero_bytes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size  - =  bytes_can_write ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > tx - > rw_pos  + =  bytes_can_write ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    xSemaphoreGive ( p_i2s_obj [ i2s_num ] - > tx - > mux ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-29 13:16:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								esp_err_t  i2s_read ( i2s_port_t  i2s_num ,  void  * dest ,  size_t  size ,  size_t  * bytes_read ,  TickType_t  ticks_to_wait )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    char  * data_ptr ,  * dest_byte ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  bytes_can_read ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * bytes_read  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dest_byte  =  ( char  * ) dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( i2s_num  <  I2S_NUM_MAX ) ,  " i2s_num error " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( size  <  I2S_MAX_BUFFER_SIZE ) ,  " size is too large " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    I2S_CHECK ( ( p_i2s_obj [ i2s_num ] - > rx ) ,  " rx NULL " ,  ESP_ERR_INVALID_ARG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    xSemaphoreTake ( p_i2s_obj [ i2s_num ] - > rx - > mux ,  ( portTickType ) portMAX_DELAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_pm_lock_acquire ( p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    while  ( size  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( p_i2s_obj [ i2s_num ] - > rx - > rw_pos  = =  p_i2s_obj [ i2s_num ] - > rx - > buf_size  | |  p_i2s_obj [ i2s_num ] - > rx - > curr_ptr  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( xQueueReceive ( p_i2s_obj [ i2s_num ] - > rx - > queue ,  & p_i2s_obj [ i2s_num ] - > rx - > curr_ptr ,  ticks_to_wait )  = =  pdFALSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            p_i2s_obj [ i2s_num ] - > rx - > rw_pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data_ptr  =  ( char * ) p_i2s_obj [ i2s_num ] - > rx - > curr_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        data_ptr  + =  p_i2s_obj [ i2s_num ] - > rx - > rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bytes_can_read  =  p_i2s_obj [ i2s_num ] - > rx - > buf_size  -  p_i2s_obj [ i2s_num ] - > rx - > rw_pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( bytes_can_read  >  size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bytes_can_read  =  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        memcpy ( dest_byte ,  data_ptr ,  bytes_can_read ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        size  - =  bytes_can_read ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        dest_byte  + =  bytes_can_read ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        p_i2s_obj [ i2s_num ] - > rx - > rw_pos  + =  bytes_can_read ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ( * bytes_read )  + =  bytes_can_read ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 17:47:42 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PM_ENABLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    esp_pm_lock_release ( p_i2s_obj [ i2s_num ] - > pm_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-12-29 17:29:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    xSemaphoreGive ( p_i2s_obj [ i2s_num ] - > rx - > mux ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-11 19:37:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  ESP_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 18:40:46 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}