components/driver/i2s.c
/**
 * @brief   Write data to I2S DMA transmit buffer.
 * @note    Many ticks pass without space becoming available in the DMA
 *          transmit buffer, then the function will return (note that if the
 *          data is written to the DMA buffer in pieces, the overall operation
 *          may still take longer than this timeout.) Pass portMAX_DELAY for no
 *          timeout.
 *
 * @param       i2s_num             I2S device number
 * @param       src                 Source address to write from
 * @param       size                Size of data in bytes
 * @param[out]  bytes_written       Number of bytes written, if timeout, the result will be less than the size passed in.
 * @param       ticks_to_wait       TX buffer wait timeout in RTOS ticks. If this
 * @return
 *     - ESP_OK               Success
 *     - ESP_ERR_INVALID_ARG  Parameter error
 */
@brief   Write data to I2S DMA transmit buffer.
@note    Many ticks pass without space becoming available in the DMA
transmit buffer, then the function will return (note that if the
data is written to the DMA buffer in pieces, the overall operation
may still take longer than this timeout.) Pass portMAX_DELAY for no
timeout.

@param       i2s_num             I2S device number
@param       src                 Source address to write from
@param       size                Size of data in bytes
@param[out]  bytes_written       Number of bytes written, if timeout, the result will be less than the size passed in.
@param       ticks_to_wait       TX buffer wait timeout in RTOS ticks. If this
@return
- ESP_OK               Success
- ESP_ERR_INVALID_ARG  Parameter error
@brief Write data to I2S DMA transmit buffer . @note Many ticks pass without space becoming available in the DMA transmit buffer then the function will return ( note that if the data is written to the DMA buffer in pieces the overall operation may still take longer than this timeout . ) Pass portMAX_DELAY for no timeout . @param i2s_num I2S device number @param src Source address to write from @param size Size of data in bytes @param [ out ] bytes_written Number of bytes written if timeout the result will be less than the size passed in . @param ticks_to_wait TX buffer wait timeout in RTOS ticks . If this @return - ESP_OK Success - ESP_ERR_INVALID_ARG Parameter error
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)
{
    esp_err_t ret = ESP_OK;
    char *data_ptr, *src_byte;
    size_t bytes_can_write;
    *bytes_written = 0;
    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]->tx), ESP_ERR_INVALID_ARG, TAG, "TX mode is not enabled");
    xSemaphoreTake(p_i2s[i2s_num]->tx->mux, (portTickType)portMAX_DELAY);
#ifdef CONFIG_PM_ENABLE
    esp_pm_lock_acquire(p_i2s[i2s_num]->pm_lock);
#endif
    src_byte = (char *)src;
    while (size > 0) {
        if (p_i2s[i2s_num]->tx->rw_pos == p_i2s[i2s_num]->tx->buf_size || p_i2s[i2s_num]->tx->curr_ptr == NULL) {
            if (xQueueReceive(p_i2s[i2s_num]->tx->queue, &p_i2s[i2s_num]->tx->curr_ptr, ticks_to_wait) == pdFALSE) {
                ret = ESP_ERR_TIMEOUT;
                break;
            }
            p_i2s[i2s_num]->tx->rw_pos = 0;
        }
        ESP_LOGD(TAG, "size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %d", size, p_i2s[i2s_num]->tx->rw_pos, p_i2s[i2s_num]->tx->buf_size, (int)p_i2s[i2s_num]->tx->curr_ptr);
        data_ptr = (char *)p_i2s[i2s_num]->tx->curr_ptr;
        data_ptr += p_i2s[i2s_num]->tx->rw_pos;
        bytes_can_write = p_i2s[i2s_num]->tx->buf_size - p_i2s[i2s_num]->tx->rw_pos;
        if (bytes_can_write > size) {
            bytes_can_write = size;
        }
        memcpy(data_ptr, src_byte, bytes_can_write);
        size -= bytes_can_write;
        src_byte += bytes_can_write;
        p_i2s[i2s_num]->tx->rw_pos += bytes_can_write;
        (*bytes_written) += bytes_can_write;
    }
#ifdef CONFIG_PM_ENABLE
    esp_pm_lock_release(p_i2s[i2s_num]->pm_lock);
#endif
    xSemaphoreGive(p_i2s[i2s_num]->tx->mux);
    return ret;
}
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 ) { esp_err_t ret = ESP_OK ; char * data_ptr , * src_byte ; size_t bytes_can_write ; * bytes_written = 0 ; ESP_RETURN_ON_FALSE ( ( i2s_num < I2S_NUM_MAX ) , ESP_ERR_INVALID_ARG , TAG , " " ) ; ESP_RETURN_ON_FALSE ( ( p_i2s [ i2s_num ] -> tx ) , ESP_ERR_INVALID_ARG , TAG , " " ) ; xSemaphoreTake ( p_i2s [ i2s_num ] -> tx -> mux , ( portTickType ) portMAX_DELAY ) ; #ifdef CONFIG_PM_ENABLE esp_pm_lock_acquire ( p_i2s [ i2s_num ] -> pm_lock ) ; #endif src_byte = ( char * ) src ; while ( size > 0 ) { if ( p_i2s [ i2s_num ] -> tx -> rw_pos == p_i2s [ i2s_num ] -> tx -> buf_size || p_i2s [ i2s_num ] -> tx -> curr_ptr == NULL ) { if ( xQueueReceive ( p_i2s [ i2s_num ] -> tx -> queue , & p_i2s [ i2s_num ] -> tx -> curr_ptr , ticks_to_wait ) == pdFALSE ) { ret = ESP_ERR_TIMEOUT ; break ; } p_i2s [ i2s_num ] -> tx -> rw_pos = 0 ; } ESP_LOGD ( TAG , " " , size , p_i2s [ i2s_num ] -> tx -> rw_pos , p_i2s [ i2s_num ] -> tx -> buf_size , ( int ) p_i2s [ i2s_num ] -> tx -> curr_ptr ) ; data_ptr = ( char * ) p_i2s [ i2s_num ] -> tx -> curr_ptr ; data_ptr += p_i2s [ i2s_num ] -> tx -> rw_pos ; bytes_can_write = p_i2s [ i2s_num ] -> tx -> buf_size - p_i2s [ i2s_num ] -> tx -> rw_pos ; if ( bytes_can_write > size ) { bytes_can_write = size ; } memcpy ( data_ptr , src_byte , bytes_can_write ) ; size -= bytes_can_write ; src_byte += bytes_can_write ; p_i2s [ i2s_num ] -> tx -> rw_pos += bytes_can_write ; ( * bytes_written ) += bytes_can_write ; } #ifdef CONFIG_PM_ENABLE esp_pm_lock_release ( p_i2s [ i2s_num ] -> pm_lock ) ; #endif xSemaphoreGive ( p_i2s [ i2s_num ] -> tx -> mux ) ; return ret ; }
@brief   Write data to I2S DMA transmit buffer.
@brief Write data to I2S DMA transmit buffer .