|
|
@@ -36,8 +36,10 @@
|
|
|
#include "esp_intr.h"
|
|
|
#include "esp_err.h"
|
|
|
#include "esp_log.h"
|
|
|
+#include "esp_pm.h"
|
|
|
|
|
|
static const char* I2S_TAG = "I2S";
|
|
|
+
|
|
|
#define I2S_CHECK(a, str, ret) if (!(a)) { \
|
|
|
ESP_LOGE(I2S_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
|
|
return (ret); \
|
|
|
@@ -90,6 +92,9 @@ typedef struct {
|
|
|
bool use_apll; /*!< I2S use APLL clock */
|
|
|
bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor on underflow */
|
|
|
int fixed_mclk; /*!< I2S fixed MLCK clock */
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ esp_pm_lock_handle_t pm_lock;
|
|
|
+#endif
|
|
|
} i2s_obj_t;
|
|
|
|
|
|
static i2s_obj_t *p_i2s_obj[I2S_NUM_MAX] = {0};
|
|
|
@@ -524,7 +529,6 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg)
|
|
|
}
|
|
|
xQueueSendFromISR(p_i2s->i2s_queue, (void * )&i2s_event, &high_priority_task_awoken);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
if (i2s_reg->int_st.in_suc_eof && p_i2s->rx) {
|
|
|
@@ -1063,6 +1067,14 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
|
|
|
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;
|
|
|
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_driver",
|
|
|
+ &p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+ if (err != ESP_OK) {
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+#endif //CONFIG_PM_ENABLE
|
|
|
//To make sure hardware is enabled before any hardware register operations.
|
|
|
if (i2s_num == I2S_NUM_1) {
|
|
|
periph_module_enable(PERIPH_I2S1_MODULE);
|
|
|
@@ -1073,6 +1085,11 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
|
|
|
//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) {
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ if (p_i2s_obj[i2s_num]->pm_lock) {
|
|
|
+ esp_pm_lock_delete(p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+ }
|
|
|
+#endif
|
|
|
free(p_i2s_obj[i2s_num]);
|
|
|
p_i2s_obj[i2s_num] = NULL;
|
|
|
ESP_LOGE(I2S_TAG, "Register I2S Interrupt error");
|
|
|
@@ -1128,6 +1145,11 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
|
|
|
if(p_i2s_obj[i2s_num]->use_apll) {
|
|
|
rtc_clk_apll_enable(0, 0, 0, 0, 0);
|
|
|
}
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ if (p_i2s_obj[i2s_num]->pm_lock) {
|
|
|
+ esp_pm_lock_delete(p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
free(p_i2s_obj[i2s_num]);
|
|
|
p_i2s_obj[i2s_num] = NULL;
|
|
|
@@ -1161,6 +1183,9 @@ esp_err_t i2s_write(i2s_port_t i2s_num, const void *src, size_t size, size_t *by
|
|
|
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);
|
|
|
xSemaphoreTake(p_i2s_obj[i2s_num]->tx->mux, (portTickType)portMAX_DELAY);
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ esp_pm_lock_acquire(p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+#endif
|
|
|
src_byte = (char *)src;
|
|
|
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) {
|
|
|
@@ -1182,6 +1207,10 @@ esp_err_t i2s_write(i2s_port_t i2s_num, const void *src, size_t size, size_t *by
|
|
|
p_i2s_obj[i2s_num]->tx->rw_pos += bytes_can_write;
|
|
|
(*bytes_written) += bytes_can_write;
|
|
|
}
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ esp_pm_lock_release(p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+#endif
|
|
|
+
|
|
|
xSemaphoreGive(p_i2s_obj[i2s_num]->tx->mux);
|
|
|
return ESP_OK;
|
|
|
}
|
|
|
@@ -1292,6 +1321,9 @@ esp_err_t i2s_read(i2s_port_t i2s_num, void *dest, size_t size, size_t *bytes_re
|
|
|
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);
|
|
|
xSemaphoreTake(p_i2s_obj[i2s_num]->rx->mux, (portTickType)portMAX_DELAY);
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ esp_pm_lock_acquire(p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+#endif
|
|
|
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) {
|
|
|
@@ -1311,6 +1343,9 @@ esp_err_t i2s_read(i2s_port_t i2s_num, void *dest, size_t size, size_t *bytes_re
|
|
|
p_i2s_obj[i2s_num]->rx->rw_pos += bytes_can_read;
|
|
|
(*bytes_read) += bytes_can_read;
|
|
|
}
|
|
|
+#ifdef CONFIG_PM_ENABLE
|
|
|
+ esp_pm_lock_release(p_i2s_obj[i2s_num]->pm_lock);
|
|
|
+#endif
|
|
|
xSemaphoreGive(p_i2s_obj[i2s_num]->rx->mux);
|
|
|
return ESP_OK;
|
|
|
}
|
|
|
@@ -1340,5 +1375,3 @@ int i2s_pop_sample(i2s_port_t i2s_num, void *sample, TickType_t ticks_to_wait)
|
|
|
return bytes_pop;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|