components/driver/i2s.c
/**
 * @brief   Read data from I2S DMA receive buffer
 * @note    If the built-in ADC mode is enabled, we should call i2s_adc_enable and i2s_adc_disable around the whole reading process,
 *          to prevent the data getting corrupted.
 *
 * @param       i2s_num         I2S device number
 * @param       dest            Destination address to read into
 * @param       size            Size of data in bytes
 * @param[out]  bytes_read      Number of bytes read, if timeout, bytes read will be less than the size passed in.
 * @param       ticks_to_wait   RX buffer wait timeout in RTOS ticks. If this many ticks pass without bytes becoming available in the DMA receive buffer, then the function will return (note that if data is read from the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout.
 * @return
 *     - ESP_OK               Success
 *     - ESP_ERR_INVALID_ARG  Parameter error
 */
@brief   Read data from I2S DMA receive buffer
@note    If the built-in ADC mode is enabled, we should call i2s_adc_enable and i2s_adc_disable around the whole reading process,
to prevent the data getting corrupted.

@param       i2s_num         I2S device number
@param       dest            Destination address to read into
@param       size            Size of data in bytes
@param[out]  bytes_read      Number of bytes read, if timeout, bytes read will be less than the size passed in.
@param       ticks_to_wait   RX buffer wait timeout in RTOS ticks. If this many ticks pass without bytes becoming available in the DMA receive buffer, then the function will return (note that if data is read from the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout.
@return
- ESP_OK               Success
- ESP_ERR_INVALID_ARG  Parameter error
@brief Read data from I2S DMA receive buffer @note If the built - in ADC mode is enabled we should call i2s_adc_enable and i2s_adc_disable around the whole reading process to prevent the data getting corrupted . @param i2s_num I2S device number @param dest Destination address to read into @param size Size of data in bytes @param [ out ] bytes_read Number of bytes read if timeout bytes read will be less than the size passed in . @param ticks_to_wait RX buffer wait timeout in RTOS ticks . If this many ticks pass without bytes becoming available in the DMA receive buffer then the function will return ( note that if data is read from the DMA buffer in pieces the overall operation may still take longer than this timeout . ) Pass portMAX_DELAY for no timeout . @return - ESP_OK Success - ESP_ERR_INVALID_ARG Parameter error
esp_err_t i2s_read(i2s_port_t i2s_num, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait)
{
    esp_err_t ret = ESP_OK;
    char *data_ptr, *dest_byte;
    int bytes_can_read;
    *bytes_read = 0;
    dest_byte = (char *)dest;
    ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error");
    ESP_RETURN_ON_FALSE((p_i2s[i2s_num]->rx), ESP_ERR_INVALID_ARG, TAG, "RX mode is not enabled");
    xSemaphoreTake(p_i2s[i2s_num]->rx->mux, (portTickType)portMAX_DELAY);
#ifdef CONFIG_PM_ENABLE
    esp_pm_lock_acquire(p_i2s[i2s_num]->pm_lock);
#endif
    while (size > 0) {
        if (p_i2s[i2s_num]->rx->rw_pos == p_i2s[i2s_num]->rx->buf_size || p_i2s[i2s_num]->rx->curr_ptr == NULL) {
            if (xQueueReceive(p_i2s[i2s_num]->rx->queue, &p_i2s[i2s_num]->rx->curr_ptr, ticks_to_wait) == pdFALSE) {
                ret = ESP_ERR_TIMEOUT;
                break;
            }
            p_i2s[i2s_num]->rx->rw_pos = 0;
        }
        data_ptr = (char *)p_i2s[i2s_num]->rx->curr_ptr;
        data_ptr += p_i2s[i2s_num]->rx->rw_pos;
        bytes_can_read = p_i2s[i2s_num]->rx->buf_size - p_i2s[i2s_num]->rx->rw_pos;
        if (bytes_can_read > (int)size) {
            bytes_can_read = size;
        }
        memcpy(dest_byte, data_ptr, bytes_can_read);
        size -= bytes_can_read;
        dest_byte += bytes_can_read;
        p_i2s[i2s_num]->rx->rw_pos += bytes_can_read;
        (*bytes_read) += bytes_can_read;
    }
#ifdef CONFIG_PM_ENABLE
    esp_pm_lock_release(p_i2s[i2s_num]->pm_lock);
#endif
    xSemaphoreGive(p_i2s[i2s_num]->rx->mux);
    return ret;
}
esp_err_t i2s_read ( i2s_port_t i2s_num , void * dest , size_t size , size_t * bytes_read , TickType_t ticks_to_wait ) { esp_err_t ret = ESP_OK ; char * data_ptr , * dest_byte ; int bytes_can_read ; * bytes_read = 0 ; dest_byte = ( char * ) dest ; ESP_RETURN_ON_FALSE ( ( i2s_num < I2S_NUM_MAX ) , ESP_ERR_INVALID_ARG , TAG , " " ) ; ESP_RETURN_ON_FALSE ( ( p_i2s [ i2s_num ] -> rx ) , ESP_ERR_INVALID_ARG , TAG , " " ) ; xSemaphoreTake ( p_i2s [ i2s_num ] -> rx -> mux , ( portTickType ) portMAX_DELAY ) ; #ifdef CONFIG_PM_ENABLE esp_pm_lock_acquire ( p_i2s [ i2s_num ] -> pm_lock ) ; #endif while ( size > 0 ) { if ( p_i2s [ i2s_num ] -> rx -> rw_pos == p_i2s [ i2s_num ] -> rx -> buf_size || p_i2s [ i2s_num ] -> rx -> curr_ptr == NULL ) { if ( xQueueReceive ( p_i2s [ i2s_num ] -> rx -> queue , & p_i2s [ i2s_num ] -> rx -> curr_ptr , ticks_to_wait ) == pdFALSE ) { ret = ESP_ERR_TIMEOUT ; break ; } p_i2s [ i2s_num ] -> rx -> rw_pos = 0 ; } data_ptr = ( char * ) p_i2s [ i2s_num ] -> rx -> curr_ptr ; data_ptr += p_i2s [ i2s_num ] -> rx -> rw_pos ; bytes_can_read = p_i2s [ i2s_num ] -> rx -> buf_size - p_i2s [ i2s_num ] -> rx -> rw_pos ; if ( bytes_can_read > ( int ) size ) { bytes_can_read = size ; } memcpy ( dest_byte , data_ptr , bytes_can_read ) ; size -= bytes_can_read ; dest_byte += bytes_can_read ; p_i2s [ i2s_num ] -> rx -> rw_pos += bytes_can_read ; ( * bytes_read ) += bytes_can_read ; } #ifdef CONFIG_PM_ENABLE esp_pm_lock_release ( p_i2s [ i2s_num ] -> pm_lock ) ; #endif xSemaphoreGive ( p_i2s [ i2s_num ] -> rx -> mux ) ; return ret ; }
@brief   Read data from I2S DMA receive buffer
 @note    If the built-in ADC mode is enabled, we should call i2s_adc_enable and i2s_adc_disable around the whole reading process,
          to prevent the data getting corrupted.
@brief Read data from I2S DMA receive buffer @note If the built - in ADC mode is enabled we should call i2s_adc_enable and i2s_adc_disable around the whole reading process to prevent the data getting corrupted .