Skip to content

Commit 78c5e6e

Browse files
committed
bugfix(esp_codec_dev): Fixed racing condition when playback record re-enable during another running
1 parent b61b58a commit 78c5e6e

File tree

11 files changed

+748
-99
lines changed

11 files changed

+748
-99
lines changed

components/esp_codec_dev/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# Changelog
22

3-
## Un-Release
3+
## v1.5.1
44

55
### Bug Fixed
66

77
- Fixed the register configuration for es8311 when playing 8kHz audio without using MCLK.
8+
- Fixed race condition when record or playback disable and enable during another running.
9+
- Fixed test_app build failed on esp-idf v6.x.
10+
- Added support for duplex I2S TX and RX use multiple codecs (data_if use same port with one channel only).
11+
- Added `esp_codec_dev_dump_reg` to dump codec registers.
812

913
## v1.5.0
1014

components/esp_codec_dev/device/es8311/es8311.c

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ typedef struct {
1919
float hw_gain;
2020
} audio_codec_es8311_t;
2121

22+
typedef struct {
23+
audio_codec_es8311_t *adc;
24+
audio_codec_es8311_t *dac;
25+
} paired_8311_codec_t;
26+
2227
/*
2328
* Clock coefficient structure
2429
*/
@@ -154,6 +159,48 @@ static const esp_codec_dev_vol_range_t vol_range = {
154159
},
155160
};
156161

162+
static paired_8311_codec_t paired_8311;
163+
164+
static inline bool es8311_is_used(void)
165+
{
166+
if (paired_8311.adc || paired_8311.dac) {
167+
return true;
168+
}
169+
return false;
170+
}
171+
172+
static inline void es8311_add_pair(audio_codec_es8311_t *codec)
173+
{
174+
if (codec->cfg.codec_mode & ESP_CODEC_DEV_WORK_MODE_ADC) {
175+
if (paired_8311.adc == NULL) {
176+
paired_8311.adc = codec;
177+
return;
178+
}
179+
}
180+
if (codec->cfg.codec_mode & ESP_CODEC_DEV_WORK_MODE_DAC) {
181+
if (paired_8311.dac == NULL) {
182+
paired_8311.dac = codec;
183+
return;
184+
}
185+
}
186+
}
187+
188+
static void es8311_remove_pair(audio_codec_es8311_t *codec)
189+
{
190+
if (codec->cfg.codec_mode & ESP_CODEC_DEV_WORK_MODE_ADC) {
191+
if (paired_8311.adc == codec) {
192+
paired_8311.adc = NULL;
193+
return;
194+
}
195+
}
196+
if (codec->cfg.codec_mode & ESP_CODEC_DEV_WORK_MODE_DAC) {
197+
if (paired_8311.dac == codec) {
198+
paired_8311.dac = NULL;
199+
return;
200+
}
201+
}
202+
}
203+
157204
static int es8311_write_reg(audio_codec_es8311_t *codec, int reg, int value)
158205
{
159206
return codec->cfg.ctrl_if->write_reg(codec->cfg.ctrl_if, reg, 1, &value, 1);
@@ -240,6 +287,10 @@ static int get_coeff(uint32_t mclk, uint32_t rate)
240287

241288
static int es8311_suspend(audio_codec_es8311_t *codec)
242289
{
290+
es8311_remove_pair(codec);
291+
if (es8311_is_used()) {
292+
return ESP_CODEC_DEV_OK;
293+
}
243294
int ret = es8311_write_reg(codec, ES8311_DAC_REG32, 0x00);
244295
ret |= es8311_write_reg(codec, ES8311_ADC_REG17, 0x00);
245296
ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG0E, 0xFF);
@@ -289,8 +340,7 @@ static int es8311_start(audio_codec_es8311_t *codec)
289340
}
290341
dac_iface &= 0xBF;
291342
adc_iface &= 0xBF;
292-
adc_iface |= BITS(6);
293-
dac_iface |= BITS(6);
343+
294344
int codec_mode = codec->cfg.codec_mode;
295345
if (codec_mode == ESP_CODEC_DEV_WORK_MODE_LINE) {
296346
ESP_LOGE(TAG, "Codec not support LINE mode");
@@ -308,7 +358,9 @@ static int es8311_start(audio_codec_es8311_t *codec)
308358

309359
ret |= es8311_write_reg(codec, ES8311_ADC_REG17, 0xBF);
310360
ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG0E, 0x02);
311-
ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG12, 0x00);
361+
if (codec_mode == ESP_CODEC_DEV_WORK_MODE_DAC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) {
362+
ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG12, 0x00);
363+
}
312364
ret |= es8311_write_reg(codec, ES8311_SYSTEM_REG14, 0x1A);
313365

314366
// pdm dmic enable or disable
@@ -324,6 +376,7 @@ static int es8311_start(audio_codec_es8311_t *codec)
324376
ret |= es8311_write_reg(codec, ES8311_ADC_REG15, 0x40);
325377
ret |= es8311_write_reg(codec, ES8311_DAC_REG37, 0x08);
326378
ret |= es8311_write_reg(codec, ES8311_GP_REG45, 0x00);
379+
es8311_add_pair(codec);
327380
return ret;
328381
}
329382

@@ -397,7 +450,7 @@ static void es8311_pa_power(audio_codec_es8311_t *codec, es_pa_setting_t pa_sett
397450
}
398451
if (pa_setting & ES_PA_SETUP) {
399452
codec->cfg.gpio_if->setup(pa_pin, AUDIO_GPIO_DIR_OUT, AUDIO_GPIO_MODE_FLOAT);
400-
}
453+
}
401454
if (pa_setting & ES_PA_ENABLE) {
402455
codec->cfg.gpio_if->set(pa_pin, codec->cfg.pa_reverted ? false : true);
403456
}
@@ -438,7 +491,7 @@ static int es8311_config_sample(audio_codec_es8311_t *codec, int sample_rate)
438491
}
439492
if (codec->cfg.use_mclk == false) {
440493
datmp = 3;
441-
if (sample_rate == 8000) {
494+
if (sample_rate == 8000) {
442495
/* When the sample rate is 8kHz, BCLK requires at least 512K (slot bit needs to be configured to 32bit).
443496
DIG_MCLK = LRCK * 256 = BCLK * 4 */
444497
datmp = 2;
@@ -603,11 +656,16 @@ static int es8311_enable(const audio_codec_if_t *h, bool enable)
603656
if (enable == codec->enabled) {
604657
return ESP_CODEC_DEV_OK;
605658
}
659+
int codec_mode = codec->cfg.codec_mode;
606660
if (enable) {
607661
ret = es8311_start(codec);
608-
es8311_pa_power(codec, ES_PA_ENABLE);
662+
if (codec_mode == ESP_CODEC_DEV_WORK_MODE_DAC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) {
663+
es8311_pa_power(codec, ES_PA_ENABLE);
664+
}
609665
} else {
610-
es8311_pa_power(codec, ES_PA_DISABLE);
666+
if (codec_mode == ESP_CODEC_DEV_WORK_MODE_DAC || codec_mode == ESP_CODEC_DEV_WORK_MODE_BOTH) {
667+
es8311_pa_power(codec, ES_PA_DISABLE);
668+
}
611669
ret = es8311_suspend(codec);
612670
}
613671
if (ret == ESP_CODEC_DEV_OK) {

components/esp_codec_dev/esp_codec_dev.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,19 @@ int esp_codec_dev_write_reg(esp_codec_dev_handle_t handle, int reg, int val)
236236
return ESP_CODEC_DEV_NOT_SUPPORT;
237237
}
238238

239+
int esp_codec_dev_dump_reg(esp_codec_dev_handle_t handle)
240+
{
241+
codec_dev_t *dev = (codec_dev_t *) handle;
242+
if (dev == NULL) {
243+
return ESP_CODEC_DEV_INVALID_ARG;
244+
}
245+
if (dev->codec_if && dev->codec_if->dump_reg) {
246+
dev->codec_if->dump_reg(dev->codec_if);
247+
return ESP_CODEC_DEV_OK;
248+
}
249+
return ESP_CODEC_DEV_NOT_SUPPORT;
250+
}
251+
239252
int esp_codec_dev_read(esp_codec_dev_handle_t handle, void *data, int len)
240253
{
241254
codec_dev_t *dev = (codec_dev_t *) handle;

components/esp_codec_dev/idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: 1.5.0
1+
version: 1.5.1
22
description: Audio codec device support for Espressif SOC
33
url: https://github.com/espressif/esp-adf/tree/master/components/esp_codec_dev
44

components/esp_codec_dev/include/esp_codec_dev.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ int esp_codec_dev_read_reg(esp_codec_dev_handle_t codec, int reg, int *val);
7474
*/
7575
int esp_codec_dev_write_reg(esp_codec_dev_handle_t codec, int reg, int val);
7676

77+
/**
78+
* @brief Dump registers from codec device
79+
* @param codec: Codec device handle
80+
* @return ESP_CODEC_DEV_OK: Read success
81+
* ESP_CODEC_DEV_INVALID_ARG: Invalid arguments
82+
* ESP_CODEC_DEV_NOT_SUPPORT: Not supported
83+
*/
84+
int esp_codec_dev_dump_reg(esp_codec_dev_handle_t codec);
85+
7786
/**
7887
* @brief Read data from codec
7988
* @param codec: Codec device handle

components/esp_codec_dev/include/esp_codec_dev_os.h

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,53 @@ extern "C" {
1111
#endif
1212

1313
/**
14-
* @brief Sleep in milliseconds
15-
* @param ms: Sleep time (unit ms)
14+
* @brief Codec device mutex handle
15+
*/
16+
typedef void *esp_codec_dev_mutex_handle_t;
17+
18+
/**
19+
* @brief Create mutex for codec device
20+
*
21+
* @return
22+
* - NULL No available resource
23+
* - Others Mutex handle
24+
*/
25+
esp_codec_dev_mutex_handle_t esp_codec_dev_mutex_create(void);
26+
27+
/**
28+
* @brief Lock mutex for codec device
29+
*
30+
* @param[in] mutex Mutex handle
31+
* @param[in] timeout_ms Wait timeout for mutex (unit ms)
32+
*
33+
* @return
34+
* - 0 On success
35+
* - Others Failed to lock
36+
*/
37+
int esp_codec_dev_mutex_lock(esp_codec_dev_mutex_handle_t mutex, int timeout_ms);
38+
39+
/**
40+
* @brief Unlock mutex for codec device
41+
*
42+
* @param[in] mutex Mutex handle
43+
*
44+
* @return
45+
* - 0 On success
46+
* - Others Failed to unlock
47+
*/
48+
int esp_codec_dev_mutex_unlock(esp_codec_dev_mutex_handle_t mutex);
49+
50+
/**
51+
* @brief Destroy mutex for codec device
52+
*
53+
* @param[in] mutex Mutex handle
54+
*/
55+
void esp_codec_dev_mutex_destroy(esp_codec_dev_mutex_handle_t mutex);
56+
57+
/**
58+
* @brief Sleep in milliseconds
59+
*
60+
* @param[in] ms Sleep time (unit ms)
1661
*/
1762
void esp_codec_dev_sleep(int ms);
1863

0 commit comments

Comments
 (0)