ESP32C3 I2S驱动支持回调函数获取数据吗
Posted: Fri Sep 03, 2021 6:21 am
目前I2S驱动只看到i2s_read接口获取数据,但这是polling方式的。是否有注册回调函数,当数据到达是调用回头函数通知上层app?
Code: Select all
/**
* @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)
{
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) {
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 ESP_OK;
}