diff --git a/components/adf_utils/cloud_services/baidu_access_token.c b/components/adf_utils/cloud_services/baidu_access_token.c index 2e46cb5c0..8ae927478 100644 --- a/components/adf_utils/cloud_services/baidu_access_token.c +++ b/components/adf_utils/cloud_services/baidu_access_token.c @@ -27,6 +27,7 @@ #include "esp_http_client.h" #include "json_utils.h" #include "esp_log.h" +#include "audio_error.h" #define BAIDU_URI_LENGTH (200) #define BAIDU_AUTH_ENDPOINT "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials" @@ -37,13 +38,17 @@ char *baidu_get_access_token(const char *access_key, const char *access_secret) { char *token = NULL; char *uri = calloc(1, BAIDU_URI_LENGTH); - assert(uri); + + AUDIO_MEM_CHECK(TAG, uri, return NULL); + snprintf(uri, BAIDU_URI_LENGTH, BAIDU_AUTH_ENDPOINT"&client_id=%s&client_secret=%s", access_key, access_secret); esp_http_client_config_t config = { .uri = uri, }; esp_http_client_handle_t http_client = esp_http_client_init(&config); + AUDIO_MEM_CHECK(TAG, http_client, return NULL); + if (esp_http_client_open(http_client, 0) != ESP_OK) { ESP_LOGE(TAG, "Error open http request to baidu auth server"); goto _exit; @@ -51,7 +56,9 @@ char *baidu_get_access_token(const char *access_key, const char *access_secret) esp_http_client_fetch_headers(http_client); int max_len = 2 * 1024; char *data = malloc(max_len); - assert(data); + + AUDIO_MEM_CHECK(TAG, data, goto _exit); + int read_index = 0, total_len = 0; while (1) { int read_len = esp_http_client_read(http_client, data + read_index, max_len - read_index); diff --git a/components/adf_utils/json_utils.c b/components/adf_utils/json_utils.c index 8728e31b0..965fa7d2b 100644 --- a/components/adf_utils/json_utils.c +++ b/components/adf_utils/json_utils.c @@ -27,6 +27,7 @@ #include #include "esp_log.h" #include "jsmn.h" +#include "audio_error.h" static const char* TAG = "JSON_UTILS"; @@ -61,7 +62,7 @@ char *json_get_token_value(const char *json_string, const char *token_name) if (jsoneq(json_string, &t[i], token_name) && i < r) { int tok_len = t[i+1].end - t[i+1].start; char *tok = calloc(1, tok_len + 1); - assert(tok); + AUDIO_MEM_CHECK(TAG, tok, return NULL); memcpy(tok, json_string + t[i+1].start, tok_len); return tok; } diff --git a/components/audio_hal/.component.mk.swp b/components/audio_hal/.component.mk.swp new file mode 100644 index 000000000..c732ce48e Binary files /dev/null and b/components/audio_hal/.component.mk.swp differ diff --git a/components/audio_hal/Kconfig.projbuild b/components/audio_hal/Kconfig.projbuild new file mode 100644 index 000000000..c51896229 --- /dev/null +++ b/components/audio_hal/Kconfig.projbuild @@ -0,0 +1,19 @@ +menu "BOARD" +choice BOARD + prompt "BOARD" + default AUDIO_KIT + help + CHOOSE MODULE + +config ESP32_LYRAT + bool "ESP32_LYRAT" + help + ESPRESSIF LYRAT BOARD + +config AUDIO_KIT + bool "AUDIO_KIT" + help + ESPRESSIF LYRAT BOARD + +endchoice +endmenu diff --git a/components/audio_hal/audio_hal.c b/components/audio_hal/audio_hal.c index b3509dd72..8db5b36e3 100644 --- a/components/audio_hal/audio_hal.c +++ b/components/audio_hal/audio_hal.c @@ -26,16 +26,23 @@ #include "driver/gpio.h" #include "esp_log.h" #include "audio_hal.h" - +#include "board.h" #include "audio_mem.h" #include "audio_mutex.h" +#include "sdkconfig.h" + +#ifdef CONFIG_ESP32_LYRAT #include "es8388.h" +#endif +#ifdef CONFIG_AUDIO_KIT +#include "AC101.h" +#endif -#define HAL_TAG "AUDIO_HAL" +static const char *TAG = "AUDIO_HAL"; #define AUDIO_HAL_CHECK_NULL(a, format, b, ...) \ if ((a) == 0) { \ - ESP_LOGE(HAL_TAG, format, ##__VA_ARGS__); \ + ESP_LOGE(TAG, format, ##__VA_ARGS__); \ return b;\ } @@ -50,6 +57,22 @@ struct audio_hal { void* handle; }; + + +#ifdef CONFIG_AUDIO_KIT +static struct audio_hal audio_hal_codecs_default[] = { + { + .audio_codec_initialize = AC101_init, + .audio_codec_deinitialize = AC101_deinit, + .audio_codec_ctrl = AC101_ctrl_state, + .audio_codec_config_iface = AC101_config_i2s, + .audio_codec_set_volume = AC101_set_voice_volume, + .audio_codec_get_volume = AC101_get_voice_volume, + } +}; +#endif + +#ifdef CONFIG_ESP32_LYRAT static struct audio_hal audio_hal_codecs_default[] = { { .audio_codec_initialize = es8388_init, @@ -60,6 +83,9 @@ static struct audio_hal audio_hal_codecs_default[] = { .audio_codec_get_volume = es8388_get_voice_volume, } }; +#endif + + audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t* audio_hal_conf, int index) { @@ -67,11 +93,18 @@ audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t* audio_hal_conf, int if (NULL != audio_hal_codecs_default[index].handle) { return audio_hal_codecs_default[index].handle; } - audio_hal_handle_t audio_hal = (audio_hal_handle_t) audio_calloc(1, sizeof(struct audio_hal)); - assert(audio_hal); + audio_hal_handle_t audio_hal =(audio_hal_handle_t) audio_calloc(1, sizeof(struct audio_hal)); + AUDIO_MEM_CHECK(TAG, audio_hal, return NULL); memcpy(audio_hal, &audio_hal_codecs_default[index], sizeof(struct audio_hal)); audio_hal->audio_hal_lock = mutex_create(); - assert(audio_hal->audio_hal_lock); + + AUDIO_MEM_CHECK(TAG, audio_hal->audio_hal_lock, { + free(audio_hal); + return NULL; + }); + + + mutex_lock(audio_hal->audio_hal_lock); ret = audio_hal->audio_codec_initialize(audio_hal_conf); ret |= audio_hal->audio_codec_config_iface(AUDIO_HAL_CODEC_MODE_BOTH, &audio_hal_conf->i2s_iface); @@ -79,7 +112,9 @@ audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t* audio_hal_conf, int audio_hal->handle = audio_hal; audio_hal_codecs_default[index].handle = audio_hal; mutex_unlock(audio_hal->audio_hal_lock); +#ifdef CONFIG_ESP32_LYRAT es8388_pa_power(true); +#endif return audio_hal; } @@ -102,7 +137,7 @@ esp_err_t audio_hal_ctrl_codec(audio_hal_handle_t audio_hal, audio_hal_codec_mod esp_err_t ret; AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1); mutex_lock(audio_hal->audio_hal_lock); - ESP_LOGI(HAL_TAG, "Codec mode is %d, Ctrl:%d", mode, audio_hal_state); + ESP_LOGI(TAG, "Codec mode is %d, Ctrl:%d", mode, audio_hal_state); ret = audio_hal->audio_codec_ctrl(mode, audio_hal_state); mutex_unlock(audio_hal->audio_hal_lock); return ret; diff --git a/components/audio_hal/board/board.h b/components/audio_hal/board/board.h index 1d1a056e2..c301ccf2c 100644 --- a/components/audio_hal/board/board.h +++ b/components/audio_hal/board/board.h @@ -28,16 +28,21 @@ #ifdef __cplusplus extern "C" { #endif +#include "sdkconfig.h" -/* SD card relateed */ +//#ifdef COFNIG_AiThinker_AUDIO_KIT +////#define BOARD ESP32_LYRAT +//#elif CONFIG_ESP32_LYRAT +////#define BOARD ESP32_LYRAT +//#endif + + +#ifdef CONFIG_ESP32_LYRAT #define SD_CARD_INTR_GPIO GPIO_NUM_34 #define SD_CARD_INTR_SEL GPIO_SEL_34 #define SD_CARD_OPEN_FILE_NUM_MAX 5 - - #define IIC_CLK 23 #define IIC_DATA 18 - /* PA */ #define GPIO_PA_EN GPIO_NUM_21 #define GPIO_SEL_PA_EN GPIO_SEL_21 @@ -52,6 +57,34 @@ extern "C" { #define IIS_LCLK 25 #define IIS_DSIN 26 #define IIS_DOUT 35 +#endif + +#ifdef CONFIG_AUDIO_KIT +/* SD card relateed */ +#define SD_CARD_INTR_GPIO GPIO_NUM_21 +#define SD_CARD_INTR_SEL GPIO_SEL_21 +#define SD_CARD_OPEN_FILE_NUM_MAX 5 + + +#define IIC_CLK 18 +#define IIC_DATA 19 + +/* PA */ +//#define GPIO_PA_EN GPIO_NUM_16 +//#define GPIO_SEL_PA_EN GPIO_SEL_16 + +/* Press button related */ +#define GPIO_SEL_REC GPIO_SEL_36 //SENSOR_VP +#define GPIO_SEL_MODE GPIO_SEL_39 //SENSOR_VN +#define GPIO_REC GPIO_NUM_36 +#define GPIO_MODE GPIO_NUM_39 + +#define IIS_SCLK 27 +#define IIS_LCLK 26 +#define IIS_DSIN 25 +#define IIS_DOUT 35 +#endif + #ifdef __cplusplus } diff --git a/components/audio_hal/component.mk b/components/audio_hal/component.mk index 5ad25a639..c8bac79d1 100644 --- a/components/audio_hal/component.mk +++ b/components/audio_hal/component.mk @@ -4,6 +4,6 @@ # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -COMPONENT_ADD_INCLUDEDIRS := ./include ./driver/es8388 ./board +COMPONENT_ADD_INCLUDEDIRS := ./include ./driver/es8388 ./board ./driver/AC101 -COMPONENT_SRCDIRS := . ./driver/es8388 ./board +COMPONENT_SRCDIRS := . ./driver/es8388 ./board ./driver/AC101 diff --git a/components/audio_hal/driver/AC101/AC101.c b/components/audio_hal/driver/AC101/AC101.c new file mode 100755 index 000000000..3260ae89e --- /dev/null +++ b/components/audio_hal/driver/AC101/AC101.c @@ -0,0 +1,387 @@ + +#include "AC101.h" +#ifdef CONFIG_AUDIO_KIT +#include +#include "esp_log.h" +#include "driver/i2c.h" +#include "board.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "audio_hal.h" + +#define AC101_TAG "AC101_DRIVER" +#define IIC_PORT I2C_NUM_1 + +#define AC_ASSERT(a, format, b, ...) \ + if ((a) != 0) { \ + ESP_LOGE(AC101_TAG, format, ##__VA_ARGS__); \ + return b;\ + } + +const i2c_config_t es_i2c_cfg = { + .mode = I2C_MODE_MASTER, + .sda_io_num = IIC_DATA, + .scl_io_num = IIC_CLK, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = 100000 +}; + +static int i2c_init() +{ + int res; + res = i2c_param_config(IIC_PORT, &es_i2c_cfg); + res |= i2c_driver_install(IIC_PORT, es_i2c_cfg.mode, 0, 0, 0); + printf("IIC init %d\r\n", res); + AC_ASSERT(res, "i2c_init error", -1); + return res; +} + +static esp_err_t i2c_example_master_read_slave(uint8_t DevAddr, uint8_t reg,uint8_t* data_rd, size_t size) +{ + if (size == 0) { + return ESP_OK; + } + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, ( DevAddr << 1 ) | WRITE_BIT, ACK_CHECK_EN); + i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, ( DevAddr << 1 ) | READ_BIT, ACK_CHECK_EN); //check or not + i2c_master_read(cmd, data_rd, size, ACK_VAL); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(IIC_PORT, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + //printf("read:%x %x\r\n",data_rd[0],data_rd[1]); + return ret; +} + +static esp_err_t AC101_Write_Reg(uint8_t reg, uint16_t val) +{ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + esp_err_t ret =0; + uint8_t send_buff[4]; + send_buff[0] = (AC101_ADDR << 1); + send_buff[1] = reg; + send_buff[2] = (val>>8) & 0xff; + send_buff[3] = val & 0xff; + ret |= i2c_master_start(cmd); + ret |= i2c_master_write(cmd, send_buff, 4, ACK_CHECK_EN); + ret |= i2c_master_stop(cmd); + ret |= i2c_master_cmd_begin(IIC_PORT, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + return ret; +} + +static uint16_t AC101_read_Reg(uint8_t reg) { + uint16_t val = 0; + uint8_t data_rd[2]; + i2c_example_master_read_slave(AC101_ADDR,reg, data_rd, 2); + val=(data_rd[0]<<8)+data_rd[1]; + return val; +} + +esp_err_t AC101_init(audio_hal_codec_config_t* codec_cfg) { + ESP_LOGI(AC101_TAG, "AC101_init"); + if(i2c_init()) return -1; + esp_err_t res; + res = AC101_Write_Reg(CHIP_AUDIO_RS, 0x123); + vTaskDelay(1000 / portTICK_PERIOD_MS); + if (ESP_OK != res) { + ESP_LOGE(AC101_TAG, "reset failed!"); + return res; + } else { + ESP_LOGI(AC101_TAG, "reset succeed"); + } + res |= AC101_Write_Reg(SPKOUT_CTRL, 0xe880); + //printf("AC101_Write_Reg----->%x\r\n",0xe880); + //printf("%x\r\n\r\n", AC101_read_Reg(SPKOUT_CTRL)); + + //Enable the PLL from 256*44.1KHz MCLK source + res |= AC101_Write_Reg(PLL_CTRL1, 0x014f); + //printf("AC101_Write_Reg----->%x\r\n",0x014f); + //printf("%x\r\n\r\n", AC101_read_Reg(PLL_CTRL1)); + res |= AC101_Write_Reg(PLL_CTRL2, 0x83c0); + + //Clocking system + res |= AC101_Write_Reg(SYSCLK_CTRL, 0x8b08); + res |= AC101_Write_Reg(MOD_CLK_ENA, 0x800c); + res |= AC101_Write_Reg(MOD_RST_CTRL, 0x800c); + res |= AC101_Write_Reg(I2S_SR_CTRL, 0x7000); //sample rate + //AIF config + res |= AC101_Write_Reg(I2S1LCK_CTRL, 0x8850); //BCLK/LRCK + res |= AC101_Write_Reg(I2S1_SDOUT_CTRL, 0xc000); // + res |= AC101_Write_Reg(I2S1_SDIN_CTRL, 0xc000); + res |= AC101_Write_Reg(I2S1_MXR_SRC, 0x2200); // + + res |= AC101_Write_Reg(ADC_SRCBST_CTRL, 0xc444); + res |= AC101_Write_Reg(ADC_SRC, 0x2040); + res |= AC101_Write_Reg(ADC_DIG_CTRL, 0x8000); + res |= AC101_Write_Reg(ADC_APC_CTRL, 0x3bc0); + + //Path Configuration + res |= AC101_Write_Reg(DAC_MXR_SRC, 0xcc00); + res |= AC101_Write_Reg(DAC_DIG_CTRL, 0x8000); + res |= AC101_Write_Reg(OMIXER_SR, 0x0081); + res |= AC101_Write_Reg(OMIXER_DACA_CTRL, 0xf080);//} + return res; +} + +int ac101_get_spk_volume(void) +{ + int res; + res = AC101_read_Reg(SPKOUT_CTRL); + res &= 0x1f; + return res; +} + +esp_err_t ac101_set_spk_volume(uint8_t volume) +{ + uint16_t res; + esp_err_t ret; + res = AC101_read_Reg(SPKOUT_CTRL); + res &= (~0x1f); + volume &= 0x1f; + res |= volume; + ret = AC101_Write_Reg(SPKOUT_CTRL,res); + return ret; +} + +int ac101_get_earph_volume(void) +{ + int res; + res = AC101_read_Reg(HPOUT_CTRL); + return (res>>4)&0x3f; +} + +esp_err_t ac101_set_earph_volume(uint8_t volume) +{ + uint16_t res,tmp; + esp_err_t ret; + res = AC101_read_Reg(HPOUT_CTRL); + tmp = ~(0x3f<<4); + res &= tmp; + volume &= 0x3f; + res |= (volume << 4); + ret = AC101_Write_Reg(HPOUT_CTRL,res); + return ret; +} + +esp_err_t ac101_set_output_mixer_gain(ac_output_mixer_gain_t gain,ac_output_mixer_source_t source) +{ + uint16_t regval,temp,clrbit; + esp_err_t ret; + regval = AC101_read_Reg(OMIXER_BST1_CTRL); + switch(source){ + case SRC_MIC1: + temp = (gain&0x7) << 6; + clrbit = ~(0x7<<6); + break; + case SRC_MIC2: + temp = (gain&0x7) << 3; + clrbit = ~(0x7<<3); + break; + case SRC_LINEIN: + temp = (gain&0x7); + clrbit = ~0x7; + break; + default: + return -1; + } + regval &= clrbit; + regval |= temp; + ret = AC101_Write_Reg(OMIXER_BST1_CTRL,regval); + return ret; +} + +esp_err_t AC101_start(ac_module_t mode) +{ + esp_err_t res = 0; + if (mode == AC_MODULE_LINE) { + } + if (mode == AC_MODULE_ADC || mode == AC_MODULE_ADC_DAC || mode == AC_MODULE_LINE) { + res |= AC101_Write_Reg(ADC_SRCBST_CTRL, 0xc444); //erji mic1 + res |= AC101_Write_Reg(ADC_APC_CTRL, 0x33c0); + res |= AC101_Write_Reg(OMIXER_SR, 0x2040); + res |= AC101_Write_Reg(OMIXER_DACA_CTRL, 0x3080); + } + if (mode == AC_MODULE_DAC || mode == AC_MODULE_ADC_DAC || mode == AC_MODULE_LINE) { + //* Enable Headphoe output 注意使用耳机时,最后开以下寄存器 + res |= AC101_Write_Reg(OMIXER_DACA_CTRL, 0xff80); //out hp & spk +// res |= AC101_Write_Reg(HPOUT_CTRL, 0xc3c1); +// res |= AC101_Write_Reg(HPOUT_CTRL, 0xcb00); +// vTaskDelay(100 / portTICK_PERIOD_MS); + res |= AC101_Write_Reg(HPOUT_CTRL, 0xF8C0); + //* Enable Speaker output + res |= AC101_Write_Reg(SPKOUT_CTRL, 0xeabd); + } + + return res; +} + +esp_err_t AC101_stop(ac_module_t mode) +{ + esp_err_t res = 0; + res |= AC101_Write_Reg(HPOUT_CTRL, 0x01); //disable earphone + res |= AC101_Write_Reg(SPKOUT_CTRL, 0xe880); //disable speaker + return res; +} + +esp_err_t AC101_deinit(void) +{ + return AC101_Write_Reg(CHIP_AUDIO_RS, 0x123); //soft reset +} + +esp_err_t AC101_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state) +{ + printf("AC101_ctrl_state\r\n"); + int res = 0; + int es_mode_t = 0; + + switch (mode) { + case AUDIO_HAL_CODEC_MODE_ENCODE: + es_mode_t = AC_MODULE_ADC; + break; + case AUDIO_HAL_CODEC_MODE_LINE_IN: + es_mode_t = AC_MODULE_LINE; + break; + case AUDIO_HAL_CODEC_MODE_DECODE: + es_mode_t = AC_MODULE_DAC; + break; + case AUDIO_HAL_CODEC_MODE_BOTH: + es_mode_t = AC_MODULE_ADC_DAC; + break; + default: + es_mode_t = AC_MODULE_DAC; + ESP_LOGW(AC101_TAG, "Codec mode not support, default is decode mode"); + break; + } + if (AUDIO_HAL_CTRL_STOP == ctrl_state) { + res = AC101_stop(es_mode_t); + } else { + res = AC101_start(es_mode_t); + } + return res; +} + +esp_err_t AC101_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t* iface) +{ + + esp_err_t res = 0; + int bits = 0; + int fmat = 0; + int sample = 0; + uint16_t regval; + //res |= es8388_config_fmt(ES_MODULE_ADC_DAC, iface->fmt); + switch(iface->bits) //0x10 + { + case AUDIO_HAL_BIT_LENGTH_8BITS: + bits = BIT_LENGTH_8BITS; + break; + case AUDIO_HAL_BIT_LENGTH_16BITS: + bits = BIT_LENGTH_16BITS; + break; + case AUDIO_HAL_BIT_LENGTH_20BITS: + bits = BIT_LENGTH_20BITS; + break; + case AUDIO_HAL_BIT_LENGTH_24BITS: + bits = BIT_LENGTH_24BITS; + break; + default: + bits = BIT_LENGTH_16BITS; + } + switch(iface->fmt) //0x10 + { + case AUDIO_HAL_I2S_NORMAL: + fmat = 0x0; + break; + case AUDIO_HAL_I2S_LEFT: + fmat = 0x01; + break; + case AUDIO_HAL_I2S_RIGHT: + fmat = 0x02; + break; + case AUDIO_HAL_I2S_DSP: + fmat = 0x03; + break; + default: + fmat = 0x00; + break; + } + switch(iface->samples) + { + case AUDIO_HAL_08K_SAMPLES: + sample = SIMPLE_RATE_8000; + break; + case AUDIO_HAL_11K_SAMPLES: + sample = SIMPLE_RATE_11052; + break; + case AUDIO_HAL_12K_SAMPLES: + sample = SIMPLE_RATE_12000; + break; + case AUDIO_HAL_16K_SAMPLES: + sample = SIMPLE_RATE_16000; + break; + case AUDIO_HAL_22K_SAMPLES: + sample = SIMPLE_RATE_22050; + break; + case AUDIO_HAL_24K_SAMPLES: + sample = SIMPLE_RATE_24000; + break; + case AUDIO_HAL_32K_SAMPLES: + sample = SIMPLE_RATE_32000; + break; + case AUDIO_HAL_44K_SAMPLES: + sample = SIMPLE_RATE_44100; + break; + case AUDIO_HAL_48K_SAMPLES: + sample = SIMPLE_RATE_48000; + break; + case AUDIO_HAL_96K_SAMPLES: + sample = SIMPLE_RATE_96000; + break; + case AUDIO_HAL_192K_SAMPLES: + sample = SIMPLE_RATE_192000; + break; + default: + sample = SIMPLE_RATE_44100; + } + regval = AC101_read_Reg(I2S1LCK_CTRL); + regval &= 0x7fc3; + regval |= (iface->mode << 15); + regval |= (bits << 4); + regval |= (fmat << 2); + res |= AC101_Write_Reg(I2S1LCK_CTRL, regval); + res |= AC101_Write_Reg(I2S_SR_CTRL, sample); + return res; +} + +esp_err_t AC101_i2s_config_clock(ac_i2s_clock_t *cfg) +{ + esp_err_t res = 0; + uint16_t regval=0; + regval = AC101_read_Reg(I2S1LCK_CTRL); + regval &= 0xe03f; + regval |= (cfg->bclk_div << 9); + regval |= (cfg->lclk_div << 6); + res = AC101_Write_Reg(I2S1LCK_CTRL, regval); + return res; +} + +esp_err_t AC101_set_voice_volume(int volume) +{ + esp_err_t res; + res = ac101_set_spk_volume(volume); + res |= ac101_set_spk_volume(volume); + return res; +} + +esp_err_t AC101_get_voice_volume(int* volume) +{ + *volume = ac101_get_spk_volume(); + return 0; +} +#endif + + + diff --git a/components/audio_hal/driver/AC101/AC101.h b/components/audio_hal/driver/AC101/AC101.h new file mode 100755 index 000000000..7c724ac37 --- /dev/null +++ b/components/audio_hal/driver/AC101/AC101.h @@ -0,0 +1,165 @@ +#ifndef __AC101_H__ +#define __AC101_H__ +#include "sdkconfig.h" +#include "audio_hal.h" +#ifdef CONFIG_AUDIO_KIT +#define AC101_ADDR 0x1a /*!< Device address*/ + +#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ +#define READ_BIT I2C_MASTER_READ /*!< I2C master read */ +#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ +#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ +#define ACK_VAL 0x0 /*!< I2C ack value */ +#define NACK_VAL 0x1 /*!< I2C nack value */ + +#define CHIP_AUDIO_RS 0x00 +#define PLL_CTRL1 0x01 +#define PLL_CTRL2 0x02 +#define SYSCLK_CTRL 0x03 +#define MOD_CLK_ENA 0x04 +#define MOD_RST_CTRL 0x05 +#define I2S_SR_CTRL 0x06 +#define I2S1LCK_CTRL 0x10 +#define I2S1_SDOUT_CTRL 0x11 +#define I2S1_SDIN_CTRL 0x12 +#define I2S1_MXR_SRC 0x13 +#define I2S1_VOL_CTRL1 0x14 +#define I2S1_VOL_CTRL2 0x15 +#define I2S1_VOL_CTRL3 0x16 +#define I2S1_VOL_CTRL4 0x17 +#define I2S1_MXR_GAIN 0x18 +#define ADC_DIG_CTRL 0x40 +#define ADC_VOL_CTRL 0x41 +#define HMIC_CTRL1 0x44 +#define HMIC_CTRL2 0x45 +#define HMIC_STATUS 0x46 +#define DAC_DIG_CTRL 0x48 +#define DAC_VOL_CTRL 0x49 +#define DAC_MXR_SRC 0x4c +#define DAC_MXR_GAIN 0x4d +#define ADC_APC_CTRL 0x50 +#define ADC_SRC 0x51 +#define ADC_SRCBST_CTRL 0x52 +#define OMIXER_DACA_CTRL 0x53 +#define OMIXER_SR 0x54 +#define OMIXER_BST1_CTRL 0x55 +#define HPOUT_CTRL 0x56 +#define SPKOUT_CTRL 0x58 +#define AC_DAC_DAPCTRL 0xa0 +#define AC_DAC_DAPHHPFC 0xa1 +#define AC_DAC_DAPLHPFC 0xa2 +#define AC_DAC_DAPLHAVC 0xa3 +#define AC_DAC_DAPLLAVC 0xa4 +#define AC_DAC_DAPRHAVC 0xa5 +#define AC_DAC_DAPRLAVC 0xa6 +#define AC_DAC_DAPHGDEC 0xa7 +#define AC_DAC_DAPLGDEC 0xa8 +#define AC_DAC_DAPHGATC 0xa9 +#define AC_DAC_DAPLGATC 0xaa +#define AC_DAC_DAPHETHD 0xab +#define AC_DAC_DAPLETHD 0xac +#define AC_DAC_DAPHGKPA 0xad +#define AC_DAC_DAPLGKPA 0xae +#define AC_DAC_DAPHGOPA 0xaf +#define AC_DAC_DAPLGOPA 0xb0 +#define AC_DAC_DAPOPT 0xb1 +#define DAC_DAP_ENA 0xb5 + +typedef enum{ + SIMPLE_RATE_8000 = 0x0000, + SIMPLE_RATE_11052 = 0x1000, + SIMPLE_RATE_12000 = 0x2000, + SIMPLE_RATE_16000 = 0x3000, + SIMPLE_RATE_22050 = 0x4000, + SIMPLE_RATE_24000 = 0x5000, + SIMPLE_RATE_32000 = 0x6000, + SIMPLE_RATE_44100 = 0x7000, + SIMPLE_RATE_48000 = 0x8000, + SIMPLE_RATE_96000 = 0x9000, + SIMPLE_RATE_192000 = 0xa000, +}ac_adda_fs_i2s1_t; + +typedef enum{ + BCLK_DIV_1 = 0x0, + BCLK_DIV_2 = 0x1, + BCLK_DIV_4 = 0x2, + BCLK_DIV_6 = 0x3, + BCLK_DIV_8 = 0x4, + BCLK_DIV_12 = 0x5, + BCLK_DIV_16 = 0x6, + BCLK_DIV_24 = 0x7, + BCLK_DIV_32 = 0x8, + BCLK_DIV_48 = 0x9, + BCLK_DIV_64 = 0xa, + BCLK_DIV_96 = 0xb, + BCLK_DIV_128 = 0xc, + BCLK_DIV_192 = 0xd, + +}ac_i2s1_bclk_div_t; + +typedef enum{ + LRCK_DIV_16 =0x0, + LRCK_DIV_32 =0x1, + LRCK_DIV_64 =0x2, + LRCK_DIV_128 =0x3, + LRCK_DIV_256 =0x4, +}ac_i2s1_lrck_div_t; + +typedef enum { + BIT_LENGTH_8BITS = 0x00, + BIT_LENGTH_16BITS = 0x01, + BIT_LENGTH_20BITS = 0x02, + BIT_LENGTH_24BITS = 0x03, +} ac_bits_length_t; + +typedef enum { + AC_MODE_MIN = -1, + AC_MODE_SLAVE = 0x00, + AC_MODE_MASTER = 0x01, + AC_MODE_MAX, +} ac_mode_sm_t; + +typedef enum { + AC_MODULE_MIN = -1, + AC_MODULE_ADC = 0x01, + AC_MODULE_DAC = 0x02, + AC_MODULE_ADC_DAC = 0x03, + AC_MODULE_LINE = 0x04, + AC_MODULE_MAX +} ac_module_t; + +typedef enum{ + SRC_MIC1 = 1, + SRC_MIC2 = 2, + SRC_LINEIN = 3, +}ac_output_mixer_source_t; + +typedef enum { + GAIN_N45DB = 0, + GAIN_N30DB = 1, + GAIN_N15DB = 2, + GAIN_0DB = 3, + GAIN_15DB = 4, + GAIN_30DB = 5, + GAIN_45DB = 6, + GAIN_60DB = 7, +} ac_output_mixer_gain_t; + +/** + * @brief Configure AC101 clock + */ +typedef struct { + ac_i2s1_bclk_div_t bclk_div; /*!< bits clock divide */ + ac_i2s1_lrck_div_t lclk_div; /*!< WS clock divide */ +} ac_i2s_clock_t; + + +esp_err_t AC101_init(audio_hal_codec_config_t* codec_cfg); +esp_err_t AC101_deinit(void); +esp_err_t AC101_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state); +esp_err_t AC101_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t* iface); +esp_err_t AC101_set_voice_volume(int volume); +esp_err_t AC101_get_voice_volume(int* volume); + +#endif +#endif diff --git a/components/audio_hal/driver/es8388/es8388.c b/components/audio_hal/driver/es8388/es8388.c index a008d773d..526799a00 100644 --- a/components/audio_hal/driver/es8388/es8388.c +++ b/components/audio_hal/driver/es8388/es8388.c @@ -21,13 +21,12 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ - +#ifdef CONFIG_ESP32_LYRAT #include #include "esp_log.h" #include "driver/i2c.h" #include "es8388.h" #include "board.h" - static const char *ES_TAG = "ES8388_DRIVER"; #define ES_ASSERT(a, format, b, ...) \ @@ -551,4 +550,5 @@ void es8388_pa_power(bool enable) } else { gpio_set_level(GPIO_PA_EN, 0); } -} \ No newline at end of file +} +#endif diff --git a/components/audio_hal/driver/es8388/es8388.h b/components/audio_hal/driver/es8388/es8388.h index 7643f12cf..45889de89 100644 --- a/components/audio_hal/driver/es8388/es8388.h +++ b/components/audio_hal/driver/es8388/es8388.h @@ -23,6 +23,9 @@ */ #ifndef __ES8388_H__ + +#include "sdkconfig.h" +#ifdef CONFIG_ESP32_LYRAT #include "esp_types.h" #include "audio_hal.h" #include "driver/i2c.h" @@ -437,5 +440,5 @@ esp_err_t es8388_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_s * - void */ void es8388_pa_power(bool enable); - +#endif #endif //__ES8388_H__ diff --git a/components/audio_hal/include/audio_hal.h b/components/audio_hal/include/audio_hal.h index 66fe2e320..31fafb05a 100644 --- a/components/audio_hal/include/audio_hal.h +++ b/components/audio_hal/include/audio_hal.h @@ -27,7 +27,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/task.h" +//<<<<<<< HEAD +//#include "sdkconfig.h" +//======= +#include "audio_error.h" +//>>>>>>> 3c90c734af8f1e1065a79b555dc4ee5798a83e61 #ifdef __cplusplus extern "C" { #endif @@ -36,6 +41,7 @@ extern "C" { typedef struct audio_hal* audio_hal_handle_t; +#ifdef CONFIG_ESP32_LYRAT #define AUDIO_HAL_ES8388_DEFAULT(){ \ .adc_input = AUDIO_HAL_ADC_INPUT_LINE1, \ .dac_output = AUDIO_HAL_DAC_OUTPUT_ALL, \ @@ -47,7 +53,21 @@ typedef struct audio_hal* audio_hal_handle_t; .bits = AUDIO_HAL_BIT_LENGTH_16BITS, \ }, \ }; +#endif +#ifdef CONFIG_AUDIO_KIT +#define AUDIO_HAL_AC101_DEFAULT(){ \ + .adc_input = AUDIO_HAL_ADC_INPUT_LINE1, \ + .dac_output = AUDIO_HAL_DAC_OUTPUT_ALL, \ + .codec_mode = AUDIO_HAL_CODEC_MODE_DECODE, \ + .i2s_iface = { \ + .mode = AUDIO_HAL_MODE_MASTER, \ + .fmt = AUDIO_HAL_I2S_NORMAL, \ + .samples = AUDIO_HAL_16K_SAMPLES, \ + .bits = AUDIO_HAL_BIT_LENGTH_16BITS, \ + }, \ +}; +#endif /** * @brief Select media hal codec mode */ @@ -99,20 +119,25 @@ typedef enum { typedef enum { AUDIO_HAL_08K_SAMPLES, /*!< set to 8k samples per second */ AUDIO_HAL_11K_SAMPLES, /*!< set to 11.025k samples per second */ + AUDIO_HAL_12K_SAMPLES, /*!< set to 12k samples per second */ AUDIO_HAL_16K_SAMPLES, /*!< set to 16k samples in per second */ AUDIO_HAL_22K_SAMPLES, /*!< set to 22.050k samples per second */ AUDIO_HAL_24K_SAMPLES, /*!< set to 24k samples in per second */ AUDIO_HAL_32K_SAMPLES, /*!< set to 32k samples in per second */ AUDIO_HAL_44K_SAMPLES, /*!< set to 44.1k samples per second */ AUDIO_HAL_48K_SAMPLES, /*!< set to 48k samples per second */ + AUDIO_HAL_96K_SAMPLES, /*!< set to 96k samples per second */ + AUDIO_HAL_192K_SAMPLES, /*!< set to 192k samples per second */ } audio_hal_iface_samples_t; /** * @brief Select I2S interface number of bits per sample */ typedef enum { + AUDIO_HAL_BIT_LENGTH_8BITS = 0, AUDIO_HAL_BIT_LENGTH_16BITS = 1, /*!< set 16 bits per sample */ - AUDIO_HAL_BIT_LENGTH_24BITS, /*!< set 24 bits per sample */ + AUDIO_HAL_BIT_LENGTH_20BITS, + AUDIO_HAL_BIT_LENGTH_24BITS, /*!< set 24 bits per sample */ AUDIO_HAL_BIT_LENGTH_32BITS, /*!< set 32 bits per sample */ } audio_hal_iface_bits_t; @@ -146,6 +171,7 @@ typedef struct { audio_hal_codec_i2s_iface_t i2s_iface; /*!< set I2S interface configuration */ } audio_hal_codec_config_t; + /** * @brief Initialize media codec driver * diff --git a/components/audio_pipeline/audio_element.c b/components/audio_pipeline/audio_element.c index eb6d15859..8bd3d3dbf 100644 --- a/components/audio_pipeline/audio_element.c +++ b/components/audio_pipeline/audio_element.c @@ -39,6 +39,7 @@ #include "audio_common.h" #include "audio_mem.h" #include "audio_mutex.h" +#include "audio_error.h" static const char *TAG = "AUDIO_ELEMENT"; @@ -390,7 +391,10 @@ void audio_element_task(void *pv) audio_element_cmd_send(el, AEL_MSG_CMD_PAUSE); if (el->buf_size > 0) { el->buf = audio_malloc(el->buf_size); - mem_assert(el->buf); + AUDIO_MEM_CHECK(TAG, el->buf, { + el->task_run = false; + ESP_LOGE(TAG, "[%s] Error malloc element buffer", el->tag); + }); } xEventGroupClearBits(el->state_event, STOPPED_BIT); while (el->task_run) { @@ -454,6 +458,9 @@ esp_err_t audio_element_set_tag(audio_element_handle_t el, const char *tag) if (tag) { el->tag = strdup(tag); + AUDIO_MEM_CHECK(TAG, el->tag, { + return ESP_ERR_NO_MEM; + }); } return ESP_OK; } @@ -472,16 +479,16 @@ esp_err_t audio_element_set_uri(audio_element_handle_t el, const char *uri) if (uri) { el->info.uri = strdup(uri); + AUDIO_MEM_CHECK(TAG, el->info.uri, { + return ESP_ERR_NO_MEM; + }); } return ESP_OK; } char *audio_element_get_uri(audio_element_handle_t el) { - if (el->info.uri) { - return el->info.uri; - } - return NULL; + return el->info.uri; } esp_err_t audio_element_msg_set_listener(audio_element_handle_t el, audio_event_iface_handle_t listener) @@ -710,7 +717,25 @@ esp_err_t audio_element_wait_for_buffer(audio_element_handle_t el, int size_expe audio_element_handle_t audio_element_init(audio_element_cfg_t *config) { audio_element_handle_t el = audio_calloc(1, sizeof(struct audio_element)); - mem_assert(el); + + AUDIO_MEM_CHECK(TAG, el, { + return NULL; + }); + + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + evt_cfg.on_cmd = audio_element_on_cmd; + evt_cfg.context = el; + evt_cfg.queue_set_size = 0; // Element have no queue_set by default. + bool _success = + ( + ((config->tag ? audio_element_set_tag(el, config->tag) : audio_element_set_tag(el, "unknown")) == ESP_OK) && + (el->lock = mutex_create()) && + (el->event = audio_event_iface_init(&evt_cfg)) && + (el->state_event = xEventGroupCreate()) + ); + + AUDIO_MEM_CHECK(TAG, _success, goto _element_init_failed); + el->open = config->open; el->process = config->process; el->close = config->close; @@ -729,23 +754,10 @@ audio_element_handle_t audio_element_init(audio_element_cfg_t *config) el->task_core = DEFAULT_ELEMENT_TASK_CORE; } el->data = config ->data; - el->lock = mutex_create(); - mem_assert(el->lock); + el->state = AEL_STATE_INIT; el->buf_size = config->buffer_len; - if (config->tag) { - audio_element_set_tag(el, config->tag); - } else { - audio_element_set_tag(el, "unknown"); - } - audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); - evt_cfg.on_cmd = audio_element_on_cmd; - evt_cfg.context = el; - evt_cfg.queue_set_size = 0; // Element have no queue_set by default. - el->event = audio_event_iface_init(&evt_cfg); - el->state_event = xEventGroupCreate(); - mem_assert(el->state_event); audio_element_info_t info = AUDIO_ELEMENT_INFO_DEFAULT(); audio_element_setinfo(el, &info); audio_element_set_input_timeout(el, portMAX_DELAY); @@ -766,6 +778,21 @@ audio_element_handle_t audio_element_init(audio_element_cfg_t *config) } return el; +_element_init_failed: + if (el->lock) { + mutex_destroy(el->lock); + } + if (el->state_event) { + vEventGroupDelete(el->state_event); + } + if (el->event) { + audio_event_iface_destroy(el->event); + } + if (el->tag) { + audio_element_set_tag(el, NULL); + } + audio_element_set_uri(el, NULL); + return NULL; } esp_err_t audio_element_deinit(audio_element_handle_t el) @@ -862,7 +889,7 @@ esp_err_t audio_element_resume(audio_element_handle_t el, float wait_for_rb_thre return ESP_FAIL; } if (!el->is_running) { - ESP_LOGW(TAG, "[%s] RESUME:Element has not running,state:%d,task_run:%d", el->tag, el->state, el->task_run); + ESP_LOGD(TAG, "[%s] RESUME:Element has not running,state:%d,task_run:%d", el->tag, el->state, el->task_run); if ((el->state == AEL_STATE_ERROR) && el->task_stack > 0) { ESP_LOGE(TAG, "[%s] RESUME:Element has error,state:%d", el->tag, el->state); return ESP_FAIL; @@ -904,7 +931,7 @@ esp_err_t audio_element_stop(audio_element_handle_t el) return ESP_OK; } if ((el->state != AEL_STATE_PAUSED) - && (el->state != AEL_STATE_RUNNING)) { + && (el->state != AEL_STATE_RUNNING)) { ESP_LOGD(TAG, "[%s] Element already stoped", el->tag); return ESP_OK; } diff --git a/components/audio_pipeline/audio_event_iface.c b/components/audio_pipeline/audio_event_iface.c index cf2e685bc..f0611de80 100644 --- a/components/audio_pipeline/audio_event_iface.c +++ b/components/audio_pipeline/audio_event_iface.c @@ -31,12 +31,10 @@ #include "esp_log.h" #include "audio_event_iface.h" +#include "audio_error.h" static const char *TAG = "AUDIO_EVT"; -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Memory address is NULL"); return ESP_ERR_NO_MEM; } -#endif typedef struct audio_event_iface_item { STAILQ_ENTRY(audio_event_iface_item) next; @@ -67,10 +65,7 @@ struct audio_event_iface { audio_event_iface_handle_t audio_event_iface_init(audio_event_iface_cfg_t *config) { audio_event_iface_handle_t evt = calloc(1, sizeof(struct audio_event_iface)); - if (evt == NULL) { - ESP_LOGE(TAG, "Allocate address is NULL"); - return NULL; - } + AUDIO_MEM_CHECK(TAG, evt, return NULL); evt->queue_set_size = config->queue_set_size; evt->internal_queue_size = config->internal_queue_size; evt->external_queue_size = config->external_queue_size; @@ -82,14 +77,25 @@ audio_event_iface_handle_t audio_event_iface_init(audio_event_iface_cfg_t *confi } if (evt->internal_queue_size) { evt->internal_queue = xQueueCreate(evt->internal_queue_size, sizeof(audio_event_iface_msg_t)); + AUDIO_MEM_CHECK(TAG, evt->internal_queue, goto _event_iface_init_failed); } if (evt->external_queue_size) { evt->external_queue = xQueueCreate(evt->external_queue_size, sizeof(audio_event_iface_msg_t)); + AUDIO_MEM_CHECK(TAG, evt->external_queue, goto _event_iface_init_failed); } else { - ESP_LOGI(TAG, "This emiiter have no queue set,%p", evt); + ESP_LOGD(TAG, "This emiiter have no queue set,%p", evt); } + STAILQ_INIT(&evt->listening_queues); return evt; +_event_iface_init_failed: + if (evt->internal_queue) { + vQueueDelete(evt->internal_queue); + } + if (evt->external_queue) { + vQueueDelete(evt->external_queue); + } + return NULL; } static esp_err_t audio_event_iface_cleanup_listener(audio_event_iface_handle_t listen) @@ -175,8 +181,10 @@ esp_err_t audio_event_iface_set_listener(audio_event_iface_handle_t evt, audio_e return ESP_ERR_INVALID_ARG; } audio_event_iface_item_t *item = calloc(1, sizeof(audio_event_iface_item_t)); - mem_assert(item); + AUDIO_MEM_CHECK(TAG, item, return ESP_ERR_NO_MEM); + if (audio_event_iface_cleanup_listener(listener) != ESP_OK) { + AUDIO_ERROR(TAG, "Error cleanup listener"); return ESP_FAIL; } item->queue = evt->external_queue; @@ -192,8 +200,9 @@ esp_err_t audio_event_iface_set_msg_listener(audio_event_iface_handle_t evt, aud return ESP_ERR_INVALID_ARG; } audio_event_iface_item_t *item = calloc(1, sizeof(audio_event_iface_item_t)); - mem_assert(item); + AUDIO_MEM_CHECK(TAG, item, return ESP_ERR_NO_MEM); if (audio_event_iface_cleanup_listener(listener) != ESP_OK) { + AUDIO_ERROR(TAG, "Error cleanup listener"); return ESP_FAIL; } item->queue = evt->internal_queue; diff --git a/components/audio_pipeline/audio_pipeline.c b/components/audio_pipeline/audio_pipeline.c index 15067c1ae..aa16ab3b6 100644 --- a/components/audio_pipeline/audio_pipeline.c +++ b/components/audio_pipeline/audio_pipeline.c @@ -38,6 +38,7 @@ #include "audio_common.h" #include "audio_mutex.h" #include "ringbuf.h" +#include "audio_error.h" static const char *TAG = "AUDIO_PIPELINE"; @@ -92,7 +93,7 @@ static esp_err_t audio_pipeline_change_state(audio_pipeline_handle_t pipeline, a static void audio_pipeline_register_element(audio_pipeline_handle_t pipeline, audio_element_handle_t el) { audio_element_item_t *el_item = audio_calloc(1, sizeof(audio_element_item_t)); - mem_assert(el_item); + AUDIO_MEM_CHECK(TAG, el_item, return); el_item->el = el; el_item->linked = true; STAILQ_INSERT_TAIL(&pipeline->el_list, el_item, next); @@ -112,7 +113,7 @@ static void audio_pipeline_unregister_element(audio_pipeline_handle_t pipeline, static void add_rb_to_audio_pipeline(audio_pipeline_handle_t pipeline, ringbuf_handle_t rb) { ringbuf_item_t *rb_item = (ringbuf_item_t *)audio_calloc(1, sizeof(ringbuf_item_t)); - mem_assert(rb_item); + AUDIO_MEM_CHECK(TAG, rb_item, return); rb_item->rb = rb; rb_item->rb_size = rb_size_get(rb); STAILQ_INSERT_TAIL(&pipeline->rb_list, rb_item, next); @@ -153,15 +154,19 @@ esp_err_t audio_pipeline_remove_listener(audio_pipeline_handle_t pipeline) audio_pipeline_handle_t audio_pipeline_init(audio_pipeline_cfg_t *config) { - audio_pipeline_handle_t pipeline = audio_calloc(1, sizeof(struct audio_pipeline)); - mem_assert(pipeline); - + audio_pipeline_handle_t pipeline; + bool _success = + ( + (pipeline = audio_calloc(1, sizeof(struct audio_pipeline))) && + (pipeline->lock = mutex_create()) + ); + + AUDIO_MEM_CHECK(TAG, _success, return NULL); STAILQ_INIT(&pipeline->el_list); STAILQ_INIT(&pipeline->rb_list); pipeline->state = AEL_STATE_INIT; pipeline->rb_size = config->rb_size; - pipeline->lock = mutex_create(); return pipeline; } @@ -180,7 +185,9 @@ esp_err_t audio_pipeline_register(audio_pipeline_handle_t pipeline, audio_elemen audio_pipeline_unregister(pipeline, el); audio_element_set_tag(el, name); audio_element_item_t *el_item = audio_calloc(1, sizeof(audio_element_item_t)); - mem_assert(el_item); + + AUDIO_MEM_CHECK(TAG, el_item, return ESP_ERR_NO_MEM); + el_item->el = el; el_item->linked = false; STAILQ_INSERT_TAIL(&pipeline->el_list, el_item, next); @@ -243,10 +250,10 @@ esp_err_t audio_pipeline_run(audio_pipeline_handle_t pipeline) STAILQ_FOREACH(el_item, &pipeline->el_list, next) { ESP_LOGD(TAG, "start el, linked:%d,state:%d,[%p]", el_item->linked, audio_element_get_state(el_item->el), el_item->el); if (el_item->linked - && ((AEL_STATE_INIT == audio_element_get_state(el_item->el)) - || (AEL_STATE_STOPPED == audio_element_get_state(el_item->el)) - || (AEL_STATE_FINISHED == audio_element_get_state(el_item->el)) - || (AEL_STATE_ERROR == audio_element_get_state(el_item->el)))) { + && ((AEL_STATE_INIT == audio_element_get_state(el_item->el)) + || (AEL_STATE_STOPPED == audio_element_get_state(el_item->el)) + || (AEL_STATE_FINISHED == audio_element_get_state(el_item->el)) + || (AEL_STATE_ERROR == audio_element_get_state(el_item->el)))) { audio_element_run(el_item->el); } } @@ -334,10 +341,16 @@ esp_err_t audio_pipeline_link(audio_pipeline_handle_t pipeline, const char *link if (!first) { audio_element_set_input_ringbuf(el, rb); } - rb_item = audio_calloc(1, sizeof(ringbuf_item_t)); - mem_assert(rb_item); - rb = rb_create(pipeline->rb_size, 1); - mem_assert(rb); + bool _success = ( + (rb_item = audio_calloc(1, sizeof(ringbuf_item_t))) && + (rb = rb_create(pipeline->rb_size, 1)) + ); + + AUDIO_MEM_CHECK(TAG, _success, { + free(rb_item); + return ESP_ERR_NO_MEM; + }); + rb_item->rb = rb; rb_item->rb_size = pipeline->rb_size; STAILQ_INSERT_TAIL(&pipeline->rb_list, rb_item, next); @@ -347,6 +360,7 @@ esp_err_t audio_pipeline_link(audio_pipeline_handle_t pipeline, const char *link } pipeline->linked = true; return ESP_OK; + } esp_err_t audio_pipeline_unlink(audio_pipeline_handle_t pipeline) @@ -381,24 +395,24 @@ esp_err_t audio_pipeline_unlink(audio_pipeline_handle_t pipeline) esp_err_t audio_pipeline_register_more(audio_pipeline_handle_t pipeline, audio_element_handle_t element_1, ...) { va_list args; - va_start (args, element_1); + va_start(args, element_1); while (element_1) { audio_pipeline_register_element(pipeline, element_1); - element_1 = va_arg (args, audio_element_handle_t); + element_1 = va_arg(args, audio_element_handle_t); } - va_end (args); + va_end(args); return ESP_OK; } esp_err_t audio_pipeline_unregister_more(audio_pipeline_handle_t pipeline, audio_element_handle_t element_1, ...) { va_list args; - va_start (args, element_1); + va_start(args, element_1); while (element_1) { audio_pipeline_unregister_element(pipeline, element_1); - element_1 = va_arg (args, audio_element_handle_t); + element_1 = va_arg(args, audio_element_handle_t); } - va_end (args); + va_end(args); return ESP_OK; } @@ -411,17 +425,17 @@ esp_err_t audio_pipeline_link_more(audio_pipeline_handle_t pipeline, audio_eleme if (pipeline->linked) { audio_pipeline_unlink(pipeline); } - va_start (args, element_1); + va_start(args, element_1); while (element_1) { audio_element_handle_t el = element_1; audio_element_item_t *el_item = audio_calloc(1, sizeof(audio_element_item_t)); - mem_assert(el_item); + AUDIO_MEM_CHECK(TAG, el_item, return ESP_ERR_NO_MEM); el_item->el = el; el_item->linked = true; STAILQ_INSERT_TAIL(&pipeline->el_list, el_item, next); idx ++; first = (idx == 1); - element_1 = va_arg (args, audio_element_handle_t); + element_1 = va_arg(args, audio_element_handle_t); if (NULL == element_1) { audio_element_set_input_ringbuf(el, rb); } else { @@ -429,14 +443,14 @@ esp_err_t audio_pipeline_link_more(audio_pipeline_handle_t pipeline, audio_eleme audio_element_set_input_ringbuf(el, rb); } rb = rb_create(pipeline->rb_size, 1); - mem_assert(rb); + AUDIO_MEM_CHECK(TAG, rb, return ESP_ERR_NO_MEM); add_rb_to_audio_pipeline(pipeline, rb); audio_element_set_output_ringbuf(el, rb); } ESP_LOGD(TAG, "element is %p,rb:%p", el, rb); } pipeline->linked = true; - va_end (args); + va_end(args); return ESP_OK; } @@ -457,10 +471,10 @@ esp_err_t audio_pipeline_link_insert(audio_pipeline_handle_t pipeline, bool firs esp_err_t audio_pipeline_listen_more(audio_pipeline_handle_t pipeline, audio_element_handle_t element_1, ...) { va_list args; - va_start (args, element_1); + va_start(args, element_1); while (element_1) { audio_element_handle_t el = element_1; - element_1 = va_arg (args, audio_element_handle_t); + element_1 = va_arg(args, audio_element_handle_t); QueueHandle_t que = audio_element_get_event_queue(el); audio_event_iface_msg_t dummy = {0}; // while (xQueueReceive(que, &dummy, 0) == pdTRUE); @@ -473,7 +487,7 @@ esp_err_t audio_pipeline_listen_more(audio_pipeline_handle_t pipeline, audio_ele } } } - va_end (args); + va_end(args); return ESP_OK; } diff --git a/components/audio_pipeline/ringbuf.c b/components/audio_pipeline/ringbuf.c index 769f75d2a..9078469b2 100644 --- a/components/audio_pipeline/ringbuf.c +++ b/components/audio_pipeline/ringbuf.c @@ -30,18 +30,18 @@ #include "freertos/queue.h" #include "ringbuf.h" #include "esp_log.h" -#include "esp_err.h" #include "audio_mem.h" +#include "audio_error.h" -const char *TAG = "RINGBUF"; +static const char *TAG = "RINGBUF"; struct ringbuf { - char *p_o; /**< Original pointer */ - char *volatile p_r; /**< Read pointer */ - char *volatile p_w; /**< Write pointer */ + char *p_o; /**< Original pointer */ + char *volatile p_r; /**< Read pointer */ + char *volatile p_w; /**< Write pointer */ volatile uint32_t fill_cnt; /**< Number of filled slots */ - uint32_t size; /**< Buffer size */ - uint32_t block_size; + uint32_t size; /**< Buffer size */ + uint32_t block_size; /**< Block size */ SemaphoreHandle_t can_read; SemaphoreHandle_t can_write; SemaphoreHandle_t task_block; @@ -49,65 +49,77 @@ struct ringbuf { QueueSetHandle_t write_set; QueueHandle_t abort_read; QueueHandle_t abort_write; - bool is_done_write; //to prevent infinite blocking for buffer read + bool is_done_write; /**< to prevent infinite blocking for buffer read */ }; static esp_err_t rb_abort_read(ringbuf_handle_t rb); static esp_err_t rb_abort_write(ringbuf_handle_t rb); -void rb_release(SemaphoreHandle_t handle); +static void rb_release(SemaphoreHandle_t handle); ringbuf_handle_t rb_create(int size, int block_size) { if (size < 2) { + ESP_LOGE(TAG, "Invalid size"); return NULL; } if (size % block_size != 0) { + ESP_LOGE(TAG, "Invalid size"); return NULL; } - ringbuf_handle_t rb = audio_malloc(sizeof(struct ringbuf)); - configASSERT(rb); - char *buf = audio_calloc(1, size); - configASSERT(buf); + ringbuf_handle_t rb; + char *buf = NULL; + bool _success = + ( + (rb = audio_malloc(sizeof(struct ringbuf))) && + (buf = audio_calloc(1, size)) && + (rb->abort_read = xQueueCreate(1, sizeof(int))) && + (rb->abort_write = xQueueCreate(1, sizeof(int))) && + (rb->read_set = xQueueCreateSet(2)) && + (rb->write_set = xQueueCreateSet(2)) && + (rb->can_read = xSemaphoreCreateBinary()) && + (rb->task_block = xSemaphoreCreateMutex()) && + (rb->can_write = xSemaphoreCreateBinary()) && + (xQueueAddToSet(rb->abort_read, rb->read_set) == pdTRUE) && + (xQueueAddToSet(rb->can_read, rb->read_set) == pdTRUE) && + (xQueueAddToSet(rb->abort_write, rb->write_set) == pdTRUE) && + (xQueueAddToSet(rb->can_write, rb->write_set) == pdTRUE) + ); + + AUDIO_MEM_CHECK(TAG, _success, goto _rb_init_failed); rb->p_o = rb->p_r = rb->p_w = buf; rb->fill_cnt = 0; rb->size = size; rb->block_size = block_size; rb->is_done_write = false; - - rb->abort_read = xQueueCreate(1, sizeof(int)); - rb->abort_write = xQueueCreate(1, sizeof(int)); - rb->read_set = xQueueCreateSet(2); - rb->write_set = xQueueCreateSet(2); - rb->task_block = xSemaphoreCreateMutex(); - rb->can_read = xSemaphoreCreateBinary(); - rb->can_write = xSemaphoreCreateBinary(); - - configASSERT(rb->abort_read); - configASSERT(rb->read_set); - configASSERT(rb->write_set); - configASSERT(rb->task_block); - configASSERT(rb->can_read); - configASSERT(rb->can_write); - - xQueueAddToSet(rb->abort_read, rb->read_set); - xQueueAddToSet(rb->can_read, rb->read_set); - - xQueueAddToSet(rb->abort_write, rb->write_set); - xQueueAddToSet(rb->can_write, rb->write_set); return rb; +_rb_init_failed: + rb_destroy(rb); + return NULL; } esp_err_t rb_destroy(ringbuf_handle_t rb) { + if (rb == NULL) { + return ESP_ERR_INVALID_ARG; + } audio_free(rb->p_o); rb->p_o = NULL; - xQueueRemoveFromSet(rb->abort_read, rb->read_set); - xQueueRemoveFromSet(rb->abort_write, rb->write_set); + if (rb->read_set && rb->abort_read) { + xQueueRemoveFromSet(rb->abort_read, rb->read_set); + } + if (rb->abort_write && rb->write_set) { + xQueueRemoveFromSet(rb->abort_write, rb->write_set); + } + + if (rb->can_read && rb->read_set) { + xQueueRemoveFromSet(rb->can_read, rb->read_set); + } - xQueueRemoveFromSet(rb->can_read, rb->read_set); - xQueueRemoveFromSet(rb->can_write, rb->write_set); + if (rb->can_write && rb->write_set) { + xQueueRemoveFromSet(rb->can_write, rb->write_set); + } vQueueDelete(rb->abort_read); vQueueDelete(rb->abort_write); @@ -164,7 +176,7 @@ int rb_bytes_filled(ringbuf_handle_t rb) return rb->fill_cnt; } -void rb_release(SemaphoreHandle_t handle) +static void rb_release(SemaphoreHandle_t handle) { xSemaphoreGive(handle); } @@ -275,7 +287,6 @@ int rb_read(ringbuf_handle_t rb, char *buf, int buf_len, TickType_t ticks_to_wai if (total_read_size > 0) { rb_release(rb->can_write); } - // rb_release(rb->task_block); return total_read_size > 0 ? total_read_size : ret_val; } @@ -324,13 +335,10 @@ int rb_write(ringbuf_handle_t rb, char *buf, int buf_len, TickType_t ticks_to_wa if ((rb->p_w + write_size) > (rb->p_o + rb->size)) { int wlen1 = rb->p_o + rb->size - rb->p_w; int wlen2 = write_size - wlen1; - // ESP_LOGI(TAG, "write(p_w=%x, buf=%x, wlen1=%d)", (int)rb->p_w, (int)buf, wlen1); - // ESP_LOGI(TAG, "write(p_o=%x, buf + wlen1=%x, wlen2=%d)", (int)rb->p_o, (int)buf + wlen1, wlen2); memcpy(rb->p_w, buf, wlen1); memcpy(rb->p_o, buf + wlen1, wlen2); rb->p_w = rb->p_o + wlen2; } else { - // ESP_LOGI(TAG, "write(p_w=%x, buf=%x, write_size=%d)", (int)rb->p_w, (int)buf, write_size); memcpy(rb->p_w, buf, write_size); rb->p_w = rb->p_w + write_size; } @@ -350,7 +358,6 @@ int rb_write(ringbuf_handle_t rb, char *buf, int buf_len, TickType_t ticks_to_wa if (total_write_size > 0) { rb_release(rb->can_read); } - // rb_release(rb->task_block); return total_write_size > 0 ? total_write_size : ret_val; } @@ -358,9 +365,10 @@ static esp_err_t rb_abort_read(ringbuf_handle_t rb) { int abort = 1; if (rb == NULL) { - return ESP_FAIL; + return ESP_ERR_INVALID_ARG; } if (xQueueSend(rb->abort_read, (void *) &abort, 0) != pdPASS) { + ESP_LOGD(TAG, "Error send abort read queue"); return ESP_FAIL; } return ESP_OK; @@ -370,9 +378,10 @@ static esp_err_t rb_abort_write(ringbuf_handle_t rb) { int abort = 1; if (rb == NULL) { - return ESP_FAIL; + return ESP_ERR_INVALID_ARG; } if (xQueueSend(rb->abort_write, (void *) &abort, 0) != pdPASS) { + ESP_LOGD(TAG, "Error send abort write queue"); return ESP_FAIL; } return ESP_OK; @@ -404,7 +413,7 @@ int rb_size_get(ringbuf_handle_t rb) esp_err_t rb_done_write(ringbuf_handle_t rb) { if (rb == NULL) { - return ESP_FAIL; + return ESP_ERR_INVALID_ARG; } rb->is_done_write = true; rb_release(rb->can_read); @@ -422,7 +431,7 @@ bool rb_is_done_write(ringbuf_handle_t rb) int rb_get_size(ringbuf_handle_t rb) { if (rb == NULL) { - return ESP_FAIL; + return ESP_ERR_INVALID_ARG; } return rb->size; } diff --git a/components/audio_sal/include/audio_error.h b/components/audio_sal/include/audio_error.h new file mode 100644 index 000000000..803498932 --- /dev/null +++ b/components/audio_sal/include/audio_error.h @@ -0,0 +1,51 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#ifndef _AUDIO_ERROR_H_ +#define _AUDIO_ERROR_H_ + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef __FILENAME__ +#define __FILENAME__ __FILE__ +#endif + + +#define AUDIO_MEM_CHECK(TAG, a, action) if (!(a)) { \ + ESP_LOGE(TAG,"%s:%d (%s): %s", __FILENAME__, __LINE__, __FUNCTION__, "Memory exhausted"); \ + action; \ + } +#define AUDIO_ERROR(TAG, str) ESP_LOGE(TAG, "%s:%d (%s): %s", __FILENAME__, __LINE__, __FUNCTION__, str) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/audio_service/bluetooth_service.c b/components/audio_service/bluetooth_service.c index 9122f864d..474b3d80d 100644 --- a/components/audio_service/bluetooth_service.c +++ b/components/audio_service/bluetooth_service.c @@ -169,34 +169,36 @@ esp_err_t bluetooth_service_start(bluetooth_service_cfg_t *config) return ESP_FAIL; } if (config->mode == BLUETOOTH_A2DP_SOUCE) { - ESP_LOGE(TAG, "This working mode does not support now"); + AUDIO_ERROR(TAG, "This working mode is not supported yet"); return ESP_FAIL; } + g_bt_service = calloc(1, sizeof(bluetooth_service_t)); + AUDIO_MEM_CHECK(TAG, g_bt_service, return ESP_ERR_NO_MEM); + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { - ESP_LOGE(TAG, "initialize controller failed"); + AUDIO_ERROR(TAG, "initialize controller failed"); return ESP_FAIL; } if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) { - ESP_LOGE(TAG, "enable controller failed"); + AUDIO_ERROR(TAG, "enable controller failed"); return ESP_FAIL; } if (esp_bluedroid_init() != ESP_OK) { - ESP_LOGE(TAG, "initialize bluedroid failed"); + AUDIO_ERROR(TAG, "initialize bluedroid failed"); return ESP_FAIL; } if (esp_bluedroid_enable() != ESP_OK) { - ESP_LOGE(TAG, "enable bluedroid failed"); + AUDIO_ERROR(TAG, "enable bluedroid failed"); return ESP_FAIL; } - g_bt_service = calloc(1, sizeof(bluetooth_service_t)); - assert(g_bt_service); + if (config->device_name) { esp_bt_dev_set_device_name(config->device_name); } else { @@ -227,7 +229,7 @@ esp_err_t bluetooth_service_destroy() if (g_bt_service && (g_bt_service->stream || g_bt_service->periph)) { - ESP_LOGE(TAG, "Stream and periph need to stop first"); + AUDIO_ERROR(TAG, "Stream and periph need to stop first"); return ESP_FAIL; } if (g_bt_service) { @@ -262,7 +264,8 @@ audio_element_handle_t bluetooth_service_create_stream() cfg.destroy = _bt_stream_destroy; cfg.tag = "bt"; g_bt_service->stream = audio_element_init(&cfg); - mem_assert(g_bt_service->stream); + + AUDIO_MEM_CHECK(TAG, g_bt_service->stream, return NULL); audio_element_setdata(g_bt_service->stream, g_bt_service); diff --git a/components/audio_service/include/bluetooth_service.h b/components/audio_service/include/bluetooth_service.h index 6de4c24b9..bb5e85d44 100644 --- a/components/audio_service/include/bluetooth_service.h +++ b/components/audio_service/include/bluetooth_service.h @@ -26,7 +26,7 @@ #define _BLUETOOTH_SERVICE_H_ #include "freertos/event_groups.h" -#include "esp_err.h" +#include "audio_error.h" #include "audio_element.h" #include "esp_peripherals.h" diff --git a/components/audio_stream/fatfs_stream.c b/components/audio_stream/fatfs_stream.c index 9a0763a4d..0a6dbc13a 100644 --- a/components/audio_stream/fatfs_stream.c +++ b/components/audio_stream/fatfs_stream.c @@ -136,7 +136,7 @@ static esp_err_t _fatfs_open(audio_element_handle_t self) } fatfs->is_open = true; if (info.byte_pos && fseek(fatfs->file, info.byte_pos, SEEK_SET) != 0) { - ESP_LOGE(TAG, "Failed to seek to %d/%d", (int)info.byte_pos, (int)info.total_bytes); + ESP_LOGE(TAG, "Failed to seek to %d/%d", (int)info.byte_pos, (int)info.total_bytes); return ESP_FAIL; } @@ -192,10 +192,12 @@ static esp_err_t _fatfs_close(audio_element_handle_t self) fatfs_stream_t *fatfs = (fatfs_stream_t *)audio_element_getdata(self); if (AUDIO_STREAM_WRITER == fatfs->type - && fatfs->file - && STREAM_TYPE_WAV == fatfs->w_type) { + && fatfs->file + && STREAM_TYPE_WAV == fatfs->w_type) { wav_header_t *wav_info = (wav_header_t *) audio_malloc(sizeof(wav_header_t)); - mem_assert(wav_info); + + AUDIO_MEM_CHECK(TAG, wav_info, return ESP_ERR_NO_MEM); + if (fseek(fatfs->file, 0, SEEK_SET) != 0) { ESP_LOGE(TAG, "Error seek file ,line=%d", __LINE__); } @@ -230,9 +232,10 @@ static esp_err_t _fatfs_destroy(audio_element_handle_t self) audio_element_handle_t fatfs_stream_init(fatfs_stream_cfg_t *config) { - fatfs_stream_t *fatfs = audio_calloc(1, sizeof(fatfs_stream_t)); - mem_assert(fatfs); audio_element_handle_t el; + fatfs_stream_t *fatfs = audio_calloc(1, sizeof(fatfs_stream_t)); + + AUDIO_MEM_CHECK(TAG, fatfs, return NULL); audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG(); cfg.open = _fatfs_open; @@ -254,7 +257,11 @@ audio_element_handle_t fatfs_stream_init(fatfs_stream_cfg_t *config) cfg.read = _fatfs_read; } el = audio_element_init(&cfg); - mem_assert(el); + + AUDIO_MEM_CHECK(TAG, el, goto _fatfs_init_exit); audio_element_setdata(el, fatfs); return el; +_fatfs_init_exit: + audio_free(fatfs); + return NULL; } diff --git a/components/audio_stream/http_stream.c b/components/audio_stream/http_stream.c index 94674d66c..364ee6401 100644 --- a/components/audio_stream/http_stream.c +++ b/components/audio_stream/http_stream.c @@ -123,11 +123,13 @@ static esp_err_t _http_open(audio_element_handle_t self) .uri = uri, .event_handle = _http_event_handle, .user_data = &info, - .timeout_ms = 30*1000, + .timeout_ms = 30 * 1000, }; http->client = esp_http_client_init(&http_cfg); + AUDIO_MEM_CHECK(TAG, http->client, return ESP_ERR_NO_MEM); + if (info.byte_pos) { char rang_header[32]; snprintf(rang_header, 32, "bytes=%d-", (int)info.byte_pos); @@ -273,9 +275,10 @@ static esp_err_t _http_destroy(audio_element_handle_t self) audio_element_handle_t http_stream_init(http_stream_cfg_t *config) { - http_stream_t *http = audio_calloc(1, sizeof(http_stream_t)); - mem_assert(http); audio_element_handle_t el; + http_stream_t *http = audio_calloc(1, sizeof(http_stream_t)); + + AUDIO_MEM_CHECK(TAG, http, return NULL); audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG(); cfg.open = _http_open; @@ -295,7 +298,12 @@ audio_element_handle_t http_stream_init(http_stream_cfg_t *config) cfg.write = _http_write; } el = audio_element_init(&cfg); - mem_assert(el); + + + AUDIO_MEM_CHECK(TAG, el, { + audio_free(http); + return NULL; + }); audio_element_setdata(el, http); return el; } diff --git a/components/audio_stream/i2s_stream.c b/components/audio_stream/i2s_stream.c index 8e342434e..206a4e7fc 100644 --- a/components/audio_stream/i2s_stream.c +++ b/components/audio_stream/i2s_stream.c @@ -113,7 +113,9 @@ static esp_err_t _i2s_close(audio_element_handle_t self) i2s_stream_t *i2s = (i2s_stream_t *)audio_element_getdata(self); int index = i2s->config.i2s_config.dma_buf_count; uint8_t *buf = audio_calloc(1, i2s->config.i2s_config.dma_buf_len * 4); - mem_assert(buf); + + AUDIO_MEM_CHECK(TAG, buf, return ESP_ERR_NO_MEM); + while (index--) { i2s_write_bytes(i2s->config.i2s_port, (char *)buf, i2s->config.i2s_config.dma_buf_len * 4, portMAX_DELAY); } @@ -171,7 +173,9 @@ static int _i2s_process(audio_element_handle_t self, char *in_buffer, int in_len i2s_stream_t *i2s = (i2s_stream_t *)audio_element_getdata(self); int index = i2s->config.i2s_config.dma_buf_count; uint8_t *buf = audio_calloc(1, i2s->config.i2s_config.dma_buf_len * 4); - mem_assert(buf); + + AUDIO_MEM_CHECK(TAG, buf, return ESP_FAIL); + while (index--) { i2s_write_bytes(i2s->config.i2s_port, (char *)buf, i2s->config.i2s_config.dma_buf_len * 4, portMAX_DELAY); } @@ -220,7 +224,9 @@ audio_element_handle_t i2s_stream_init(i2s_stream_cfg_t *config) cfg.tag = "iis"; cfg.buffer_len = I2S_STREAM_BUF_SIZE; i2s_stream_t *i2s = audio_calloc(1, sizeof(i2s_stream_t)); - mem_assert(i2s); + + AUDIO_MEM_CHECK(TAG, i2s, return NULL); + memcpy(&i2s->config, config, sizeof(i2s_stream_cfg_t)); i2s->type = config->type; @@ -230,7 +236,11 @@ audio_element_handle_t i2s_stream_init(i2s_stream_cfg_t *config) cfg.write = _i2s_write; } el = audio_element_init(&cfg); - mem_assert(el); + + AUDIO_MEM_CHECK(TAG, el, { + audio_free(i2s); + return NULL; + }); audio_element_setdata(el, i2s); audio_element_info_t info; diff --git a/components/audio_stream/include/fatfs_stream.h b/components/audio_stream/include/fatfs_stream.h index 4e80066e9..2af930a8d 100644 --- a/components/audio_stream/include/fatfs_stream.h +++ b/components/audio_stream/include/fatfs_stream.h @@ -25,7 +25,7 @@ #ifndef _FATFS_STREAM_H_ #define _FATFS_STREAM_H_ -#include "esp_err.h" +#include "audio_error.h" #include "audio_element.h" #include "audio_common.h" diff --git a/components/audio_stream/include/http_stream.h b/components/audio_stream/include/http_stream.h index beead3cad..efaa76fea 100644 --- a/components/audio_stream/include/http_stream.h +++ b/components/audio_stream/include/http_stream.h @@ -25,7 +25,7 @@ #ifndef _HTTP_STREAM_H_ #define _HTTP_STREAM_H_ -#include "esp_err.h" +#include "audio_error.h" #include "audio_element.h" #include "audio_common.h" diff --git a/components/audio_stream/include/i2s_stream.h b/components/audio_stream/include/i2s_stream.h index 7534f71bd..c6e002d22 100644 --- a/components/audio_stream/include/i2s_stream.h +++ b/components/audio_stream/include/i2s_stream.h @@ -28,6 +28,7 @@ #include "driver/i2s.h" #include "audio_common.h" #include "board.h" +#include "audio_error.h" #ifdef __cplusplus extern "C" { diff --git a/components/audio_stream/include/raw_stream.h b/components/audio_stream/include/raw_stream.h index a38139beb..fcc14b425 100644 --- a/components/audio_stream/include/raw_stream.h +++ b/components/audio_stream/include/raw_stream.h @@ -25,7 +25,7 @@ #ifndef _RAW_STREAM_H_ #define _RAW_STREAM_H_ -#include "esp_err.h" +#include "audio_error.h" #include "audio_element.h" #include "audio_common.h" diff --git a/components/audio_stream/raw_stream.c b/components/audio_stream/raw_stream.c index ff0c94828..55de1d51e 100644 --- a/components/audio_stream/raw_stream.c +++ b/components/audio_stream/raw_stream.c @@ -80,7 +80,7 @@ audio_element_handle_t raw_stream_init(raw_stream_cfg_t *config) return NULL; } raw_stream_t *raw = audio_calloc(1, sizeof(raw_stream_t)); - mem_assert(raw); + AUDIO_MEM_CHECK(TAG, raw, return NULL); audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG(); cfg.task_stack = -1; // No need task @@ -88,7 +88,10 @@ audio_element_handle_t raw_stream_init(raw_stream_cfg_t *config) cfg.tag = "raw"; raw->type = config->type; audio_element_handle_t el = audio_element_init(&cfg); - mem_assert(el); + AUDIO_MEM_CHECK(TAG, el, { + audio_free(raw); + return NULL; + }); if (config->type == AUDIO_STREAM_READER) { read_raw_el = el; } else if (config->type == AUDIO_STREAM_WRITER) { diff --git a/components/esp_peripherals/component.mk b/components/esp_peripherals/component.mk index be69e98c2..7a4a29df3 100644 --- a/components/esp_peripherals/component.mk +++ b/components/esp_peripherals/component.mk @@ -5,3 +5,4 @@ COMPONENT_ADD_INCLUDEDIRS := ./include COMPONENT_SRCDIRS := . ./lib ./lib/sdcard ./lib/button ./lib/touch COMPONENT_PRIV_INCLUDEDIRS := ./lib/sdcard ./lib/button ./lib/touch +CFLAGS+=-D__FILENAME__=\"$(periph_list, entries) { if (periph->periph_id == periph_evt->periph_id - && periph_evt->state == PERIPH_STATE_RUNNING - && periph_evt->run - && !periph_evt->disabled) { - return periph_evt->run(periph_evt, msg); + && periph_evt->state == PERIPH_STATE_RUNNING + && periph_evt->run + && !periph_evt->disabled) { + return periph_evt->run(periph_evt, msg); } } return ESP_OK; @@ -98,14 +94,22 @@ static esp_err_t process_peripheral_event(audio_event_iface_msg_t *msg, void *co esp_err_t esp_periph_init(esp_periph_config_t* config) { if (g_esp_periph_obj != NULL) { - ESP_LOGW(TAG, "Peripherals have been initialized already"); + AUDIO_ERROR(TAG, "Peripherals have been initialized already"); return ESP_FAIL; } - g_esp_periph_obj = calloc(1, sizeof(esp_periph_obj_t)); - mem_assert(g_esp_periph_obj); + int _err_step = 1; + bool _success = + ( + (g_esp_periph_obj = calloc(1, sizeof(esp_periph_obj_t))) && _err_step ++ && + (g_esp_periph_obj->state_event_bits = xEventGroupCreate()) && _err_step ++ && + (g_esp_periph_obj->lock = mutex_create()) && _err_step ++ + ); + + AUDIO_MEM_CHECK(TAG, _success, { + goto _periph_init_failed; + }); STAILQ_INIT(&g_esp_periph_obj->periph_list); - g_esp_periph_obj->lock = mutex_create(); //TODO: Should we uninstall gpio isr service?? //TODO: Because gpio need for sdcard and gpio, then install isr here @@ -113,7 +117,6 @@ esp_err_t esp_periph_init(esp_periph_config_t* config) gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1); g_esp_periph_obj->run = false; - g_esp_periph_obj->state_event_bits = xEventGroupCreate(); xEventGroupClearBits(g_esp_periph_obj->state_event_bits, STARTED_BIT); xEventGroupSetBits(g_esp_periph_obj->state_event_bits, STOPPED_BIT); g_esp_periph_obj->user_context = config->user_context; @@ -125,8 +128,24 @@ esp_err_t esp_periph_init(esp_periph_config_t* config) event_cfg.context = g_esp_periph_obj; event_cfg.on_cmd = process_peripheral_event; g_esp_periph_obj->event_iface = audio_event_iface_init(&event_cfg); + + AUDIO_MEM_CHECK(TAG, g_esp_periph_obj->event_iface, goto _periph_init_failed); audio_event_iface_set_cmd_waiting_timeout(g_esp_periph_obj->event_iface, DEFAULT_ESP_PERIPH_WAIT_TICK); return ESP_OK; + +_periph_init_failed: + if (g_esp_periph_obj) { + mutex_destroy(g_esp_periph_obj->lock); + vEventGroupDelete(g_esp_periph_obj->state_event_bits); + + if (g_esp_periph_obj->event_iface) { + audio_event_iface_destroy(g_esp_periph_obj->event_iface); + } + + free(g_esp_periph_obj); + g_esp_periph_obj = NULL; + } + return ESP_FAIL; } esp_err_t esp_periph_start_timer(esp_periph_handle_t periph, TickType_t interval_tick, timer_callback callback) @@ -134,7 +153,7 @@ esp_err_t esp_periph_start_timer(esp_periph_handle_t periph, TickType_t interval if (periph->timer == NULL) { periph->timer = xTimerCreate("periph_itmer", interval_tick, pdTRUE, periph, callback); if (xTimerStart(periph->timer, 0) != pdTRUE) { - ESP_LOGE(TAG, "Error start timer"); + AUDIO_ERROR(TAG, "Error to start timer"); return ESP_FAIL; } } @@ -155,7 +174,7 @@ esp_err_t esp_periph_stop_timer(esp_periph_handle_t periph) esp_err_t esp_periph_destroy() { if (g_esp_periph_obj == NULL) { - ESP_LOGE(TAG, "Peripherals have not been initialized"); + AUDIO_ERROR(TAG, "Peripherals have not been initialized"); return ESP_FAIL; } g_esp_periph_obj->run = false; @@ -164,7 +183,7 @@ esp_err_t esp_periph_destroy() esp_periph_handle_t item, tmp; STAILQ_FOREACH_SAFE(item, &g_esp_periph_obj->periph_list, entries, tmp) { STAILQ_REMOVE(&g_esp_periph_obj->periph_list, item, esp_periph, entries); - free (item->tag); + free(item->tag); free(item); } mutex_destroy(g_esp_periph_obj->lock); @@ -181,18 +200,23 @@ esp_err_t esp_periph_destroy() esp_periph_handle_t esp_periph_create(int periph_id, const char *tag) { if (esp_periph_get_by_id(periph_id) != NULL) { - ESP_LOGE(TAG, "This peripheral has been added"); + AUDIO_ERROR(TAG, "This peripheral has been already added"); return NULL; } esp_periph_handle_t new_entry = calloc(1, sizeof(struct esp_periph)); - mem_assert(new_entry); + + AUDIO_MEM_CHECK(TAG, new_entry, return NULL); if (tag) { new_entry->tag = strdup(tag); } else { new_entry->tag = strdup("periph"); } + AUDIO_MEM_CHECK(TAG, new_entry->tag, { + free(new_entry); + return NULL; + }) new_entry->user_context = g_esp_periph_obj->user_context; new_entry->state = PERIPH_STATE_INIT; new_entry->periph_id = periph_id; @@ -204,7 +228,7 @@ esp_periph_handle_t esp_periph_get_by_id(int periph_id) esp_periph_handle_t periph; if (g_esp_periph_obj == NULL) { - ESP_LOGE(TAG, "Peripherals have not been initialized"); + AUDIO_ERROR(TAG, "Peripherals have not been initialized"); return NULL; } @@ -272,7 +296,7 @@ static void esp_periph_task(void* pv) esp_err_t esp_periph_start(esp_periph_handle_t periph) { if (g_esp_periph_obj == NULL) { - ESP_LOGE(TAG, "Peripherals have not been initialized"); + AUDIO_ERROR(TAG, "Peripherals have not been initialized"); return ESP_FAIL; } if (esp_periph_get_by_id(periph->periph_id) != NULL) { @@ -292,7 +316,7 @@ esp_err_t esp_periph_start(esp_periph_handle_t periph) DEFAULT_ESP_PERIPH_TASK_PRIO, NULL, DEFAULT_ESP_PERIPH_TASK_CORE) != pdTRUE) { - ESP_LOGE(TAG, "Error create peripheral task"); + AUDIO_ERROR(TAG, "Error create peripheral task"); g_esp_periph_obj->run = false; return ESP_FAIL; } @@ -312,7 +336,7 @@ esp_err_t esp_periph_stop(esp_periph_handle_t periph) esp_err_t esp_periph_stop_all() { if (g_esp_periph_obj == NULL) { - ESP_LOGE(TAG, "Peripherals have not been initialized"); + AUDIO_ERROR(TAG, "Peripherals have not been initialized"); return ESP_FAIL; } esp_periph_handle_t periph; @@ -413,8 +437,7 @@ audio_event_iface_handle_t esp_periph_get_event_iface() long long esp_periph_tick_get() { struct timeval te; - gettimeofday(&te, NULL); // get current time - long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds - // printf("milliseconds: %lld\n", milliseconds); + gettimeofday(&te, NULL); + long long milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000; return milliseconds; } diff --git a/components/esp_peripherals/include/esp_peripherals.h b/components/esp_peripherals/include/esp_peripherals.h index 3068eccd9..690aef9bb 100644 --- a/components/esp_peripherals/include/esp_peripherals.h +++ b/components/esp_peripherals/include/esp_peripherals.h @@ -26,7 +26,7 @@ #define _ESP_PERIPHERALS_H_ #include "freertos/event_groups.h" -#include "esp_err.h" +#include "audio_error.h" #include "audio_event_iface.h" #include "audio_common.h" diff --git a/components/esp_peripherals/include/periph_button.h b/components/esp_peripherals/include/periph_button.h index f490b487a..1a30e2629 100644 --- a/components/esp_peripherals/include/periph_button.h +++ b/components/esp_peripherals/include/periph_button.h @@ -26,7 +26,7 @@ #define _BUTTON_DEV_H_ #include "rom/queue.h" -#include "esp_err.h" +#include "audio_error.h" #include "audio_common.h" #include "esp_peripherals.h" diff --git a/components/esp_peripherals/include/periph_console.h b/components/esp_peripherals/include/periph_console.h index bf9bdfb00..02591da40 100644 --- a/components/esp_peripherals/include/periph_console.h +++ b/components/esp_peripherals/include/periph_console.h @@ -26,7 +26,7 @@ #define _PERIPH_CONSOLE_H_ #include "rom/queue.h" -#include "esp_err.h" +#include "audio_error.h" #include "esp_peripherals.h" #ifdef __cplusplus diff --git a/components/esp_peripherals/include/periph_sdcard.h b/components/esp_peripherals/include/periph_sdcard.h index 055bfc40e..87585d457 100644 --- a/components/esp_peripherals/include/periph_sdcard.h +++ b/components/esp_peripherals/include/periph_sdcard.h @@ -26,7 +26,7 @@ #define _SDCARD_DEV_H_ #include "rom/queue.h" -#include "esp_err.h" +#include "audio_error.h" #include "audio_common.h" #include "esp_peripherals.h" diff --git a/components/esp_peripherals/include/periph_touch.h b/components/esp_peripherals/include/periph_touch.h index 0081f1aa4..91ec79e24 100644 --- a/components/esp_peripherals/include/periph_touch.h +++ b/components/esp_peripherals/include/periph_touch.h @@ -26,7 +26,7 @@ #define _TOUCH_DEV_H_ #include "rom/queue.h" -#include "esp_err.h" +#include "audio_error.h" #include "audio_common.h" #include "esp_peripherals.h" diff --git a/components/esp_peripherals/include/periph_wifi.h b/components/esp_peripherals/include/periph_wifi.h index fd4d35934..7021daa82 100644 --- a/components/esp_peripherals/include/periph_wifi.h +++ b/components/esp_peripherals/include/periph_wifi.h @@ -26,7 +26,7 @@ #define _DEV_WIFI_H_ #include "rom/queue.h" -#include "esp_err.h" +#include "audio_error.h" #include "audio_common.h" #include "esp_peripherals.h" diff --git a/components/esp_peripherals/lib/button/button.c b/components/esp_peripherals/lib/button/button.c index 9f5631067..7ed35e996 100644 --- a/components/esp_peripherals/lib/button/button.c +++ b/components/esp_peripherals/lib/button/button.c @@ -34,19 +34,14 @@ #include "rom/queue.h" #include "button.h" -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif - #ifdef periph_tick_get #define tick_get periph_tick_get #else static long long tick_get() { struct timeval te; - gettimeofday(&te, NULL); // get current time - long long milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds - // printf("milliseconds: %lld\n", milliseconds); + gettimeofday(&te, NULL); + long long milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000; return milliseconds; } #endif @@ -100,7 +95,7 @@ static button_status_t button_get_state(esp_button_handle_t button, esp_button_i esp_button_handle_t button_init(button_config_t *config) { esp_button_handle_t btn = calloc(1, sizeof(struct esp_button)); - mem_assert(btn); + AUDIO_MEM_CHECK(TAG, btn, return NULL); if (config->gpio_mask <= 0) { ESP_LOGE(TAG, "required at least 1 gpio"); return NULL; @@ -108,7 +103,6 @@ esp_button_handle_t button_init(button_config_t *config) btn->gpio_mask = config->gpio_mask; btn->long_press_time_ms = config->long_press_time_ms; - if (btn->long_press_time_ms == 0) { btn->long_press_time_ms = DEFAULT_LONG_PRESS_TIME_MS; } @@ -130,7 +124,10 @@ esp_button_handle_t button_init(button_config_t *config) if (gpio_mask & 0x01) { ESP_LOGD(TAG, "Mask = %llx, current_mask = %llx, idx=%d", btn->gpio_mask, gpio_mask, gpio_num); esp_button_item_t *new_btn = calloc(1, sizeof(esp_button_item_t)); - mem_assert(new_btn); + AUDIO_MEM_CHECK(TAG, new_btn, { + button_destroy(btn); + return NULL; + }); new_btn->gpio_num = gpio_num; if (config->button_intr_handler) { gpio_set_intr_type(gpio_num, GPIO_INTR_ANYEDGE); diff --git a/components/esp_peripherals/lib/button/button.h b/components/esp_peripherals/lib/button/button.h index 0a107e6b3..32da4730d 100644 --- a/components/esp_peripherals/lib/button/button.h +++ b/components/esp_peripherals/lib/button/button.h @@ -26,6 +26,7 @@ #define _ESP_BUTTON_ #include "driver/gpio.h" +#include "audio_error.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_peripherals/lib/sdcard/sdcard.h b/components/esp_peripherals/lib/sdcard/sdcard.h index 588f63bb1..f9c43ea6f 100644 --- a/components/esp_peripherals/lib/sdcard/sdcard.h +++ b/components/esp_peripherals/lib/sdcard/sdcard.h @@ -24,7 +24,7 @@ #ifndef _ESP_SDCARD_H_ #define _ESP_SDCARD_H_ -#include "esp_err.h" +#include "audio_error.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_peripherals/lib/touch/touch.c b/components/esp_peripherals/lib/touch/touch.c index cf5677cb4..a1370e54c 100644 --- a/components/esp_peripherals/lib/touch/touch.c +++ b/components/esp_peripherals/lib/touch/touch.c @@ -34,9 +34,6 @@ #include "rom/queue.h" #include "touch.h" -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif #define TOUCHPAD_TRIGGER_THRESHOLD 100 #define TOUCHPAD_FILTER_PERIOD (portTICK_PERIOD_MS+1) @@ -92,7 +89,8 @@ static void touch_pad_isr_handler(void* arg) esp_touch_handle_t esp_touch_init(touch_config_t *config) { esp_touch_handle_t touch = calloc(1, sizeof(struct esp_touch)); - mem_assert(touch); + AUDIO_MEM_CHECK(TAG, touch, return NULL); + if (config->touch_mask <= 0) { ESP_LOGE(TAG, "required at least 1 touch"); return NULL; @@ -109,8 +107,12 @@ esp_touch_handle_t esp_touch_init(touch_config_t *config) if (touch->tap_threshold_percent == 0) { touch->tap_threshold_percent = DEFAULT_TOUCH_THRESHOLD_PERCENT; } + bool _success = (touch_pad_init() == ESP_OK); - touch_pad_init(); + AUDIO_MEM_CHECK(TAG, _success, { + free(touch); + return NULL; + }); int touch_mask = touch->touch_mask; int touch_num = 0; @@ -120,7 +122,11 @@ esp_touch_handle_t esp_touch_init(touch_config_t *config) if (touch_mask & 0x01) { ESP_LOGD(TAG, "Mask = %x, current_mask = %x, idx=%d", touch->touch_mask, touch_mask, touch_num); esp_touch_item_t *new_touch = calloc(1, sizeof(esp_touch_item_t)); - mem_assert(new_touch); + AUDIO_MEM_CHECK(TAG, new_touch, { + esp_touch_destroy(touch); + free(touch); + return NULL; + }); new_touch->touch_num = touch_num; new_touch->last_read_tick = tick_get() + touch_index * 10; touch_pad_config(touch_num, 0); @@ -184,7 +190,7 @@ static touch_status_t touch_get_state(esp_touch_handle_t touch, esp_touch_item_t touch_item->last_tap_tick = tick_get(); touch_item->long_tapped = false; ESP_LOGD(TAG, "TOUCH_TAPPED[%d] %d, threshold %d", - touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); + touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); return TOUCH_TAP; } @@ -192,7 +198,7 @@ static touch_status_t touch_get_state(esp_touch_handle_t touch, esp_touch_item_t touch_item->last_tap_tick = 0; touch_item->long_tapped = false; ESP_LOGD(TAG, "TOUCH_LONG_RELEASE[%d] %d, threshold %d", - touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); + touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); return TOUCH_LONG_RELEASE; } @@ -200,14 +206,14 @@ static touch_status_t touch_get_state(esp_touch_handle_t touch, esp_touch_item_t touch_item->last_tap_tick = 0; touch_item->long_tapped = false; ESP_LOGD(TAG, "TOUCH_RELEASE[%d] %d, threshold %d", - touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); + touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); return TOUCH_RELEASE; } if (touch_item->long_tapped == false && touch_item->tapped && tick_get() - touch_item->last_tap_tick > touch->long_tap_time_ms) { touch_item->long_tapped = true; ESP_LOGD(TAG, "TOUCH_LONG_TAP[%d] %d, threshold %d", - touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); + touch_item->touch_num, touch_item->last_read_value, touch_item->threshold_value); return TOUCH_LONG_TAP; } return TOUCH_UNCHANGE; diff --git a/components/esp_peripherals/lib/touch/touch.h b/components/esp_peripherals/lib/touch/touch.h index 2d38d9c70..6b2130858 100644 --- a/components/esp_peripherals/lib/touch/touch.h +++ b/components/esp_peripherals/lib/touch/touch.h @@ -25,6 +25,9 @@ #ifndef _ESP_TOUCH_PAD_H_ #define _ESP_TOUCH_PAD_H_ +#include "audio_error.h" + + #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_peripherals/periph_button.c b/components/esp_peripherals/periph_button.c index c9232adb9..7a8004b49 100644 --- a/components/esp_peripherals/periph_button.c +++ b/components/esp_peripherals/periph_button.c @@ -41,10 +41,6 @@ static const char* TAG = "PERIPH_BUTTON"; -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif - #define VALIDATE_BTN(periph, ret) if (!(periph && esp_periph_get_id(periph) == PERIPH_ID_BUTTON)) { \ ESP_LOGE(TAG, "Invalid BUTTON periph, at line %d", __LINE__);\ return ret;\ @@ -100,7 +96,6 @@ static void IRAM_ATTR button_intr_handler(void* param) static void button_timer_handler(xTimerHandle tmr) { esp_periph_handle_t periph = (esp_periph_handle_t) pvTimerGetTimerID(tmr); - // ESP_LOGE(TAG, "periph_id=%d", esp_periph_get_id(periph)); esp_periph_send_cmd_from_isr(periph, 0, NULL, 0); } @@ -125,9 +120,13 @@ static esp_err_t _button_init(esp_periph_handle_t self) esp_periph_handle_t periph_button_init(periph_button_cfg_t *config) { esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_BUTTON, "periph_btn"); - mem_assert(periph); + AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_button_t *periph_btn = calloc(1, sizeof(periph_button_t)); - mem_assert(periph_btn); + + AUDIO_MEM_CHECK(TAG, periph_btn, { + free(periph); + return NULL; + }); periph_btn->gpio_mask = config->gpio_mask; periph_btn->long_press_time_ms = config->long_press_time_ms; diff --git a/components/esp_peripherals/periph_console.c b/components/esp_peripherals/periph_console.c index 4ac5d6c85..e99e54369 100644 --- a/components/esp_peripherals/periph_console.c +++ b/components/esp_peripherals/periph_console.c @@ -34,17 +34,12 @@ #include "esp_vfs_dev.h" #include "rom/queue.h" #include "argtable3/argtable3.h" - #include "periph_console.h" static const char *TAG = "PERIPH_CONSOLE"; -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif - -#define CONSOLE_BUFFER_SIZE (1024) +#define CONSOLE_BUFFER_SIZE (128) #define CONSOLE_MAX_ARGUMENTS (5) static const int STOPPED_BIT = BIT1; @@ -240,10 +235,16 @@ static esp_err_t _console_init(esp_periph_handle_t self) /* Tell VFS to use UART driver */ esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - console->buffer = (char *) malloc(CONSOLE_BUFFER_SIZE); - mem_assert(console->buffer); - xTaskCreate(_console_task, "console_task", console->task_stack, self, console->task_prio, NULL); + console->buffer = (char*) malloc(CONSOLE_BUFFER_SIZE); + AUDIO_MEM_CHECK(TAG, console->buffer, { + return ESP_ERR_NO_MEM; + }); + + if (xTaskCreate(_console_task, "console_task", console->task_stack, self, console->task_prio, NULL) != pdTRUE) { + ESP_LOGE(TAG, "Error create console task, memory exhausted?"); + return ESP_FAIL; + } return ESP_OK; } @@ -251,8 +252,9 @@ static esp_err_t _console_init(esp_periph_handle_t self) esp_periph_handle_t periph_console_init(periph_console_cfg_t *config) { esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_CONSOLE, "periph_console"); + AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_console_t *console = calloc(1, sizeof(periph_console_t)); - mem_assert(console); + AUDIO_MEM_CHECK(TAG, console, return NULL); console->commands = config->commands; console->command_num = config->command_num; console->task_stack = CONSOLE_DEFAULT_TASK_STACK; @@ -265,7 +267,10 @@ esp_periph_handle_t periph_console_init(periph_console_cfg_t *config) } if (config->prompt_string) { console->prompt_string = strdup(config->prompt_string); - assert(console->prompt_string); + AUDIO_MEM_CHECK(TAG, console->prompt_string, { + free(console); + return NULL; + }); } console->state_event_bits = xEventGroupCreate(); esp_periph_set_data(periph, console); diff --git a/components/esp_peripherals/periph_sdcard.c b/components/esp_peripherals/periph_sdcard.c index e8afed024..f6a0ae4fe 100644 --- a/components/esp_peripherals/periph_sdcard.c +++ b/components/esp_peripherals/periph_sdcard.c @@ -43,16 +43,13 @@ static const char* TAG = "PERIPH_SDCARD"; -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif - #define SDCARD_CHECK_TIMEOUT_MS (20) #define VALIDATE_SDCARD(periph, ret) if (!(periph && esp_periph_get_id(periph) == PERIPH_ID_SDCARD)) { \ ESP_LOGE(TAG, "Invalid SDCARD periph, at line %d", __LINE__);\ return ret;\ } + #define tick_get periph_tick_get @@ -180,13 +177,20 @@ esp_err_t periph_sdcard_unmount(esp_periph_handle_t periph) esp_periph_handle_t periph_sdcard_init(periph_sdcard_cfg_t* sdcard_cfg) { esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_SDCARD, "periph_sdcard"); + AUDIO_MEM_CHECK(TAG, periph, return NULL); + periph_sdcard_t *sdcard = calloc(1, sizeof(periph_sdcard_t)); - mem_assert(sdcard); + AUDIO_MEM_CHECK(TAG, sdcard, return NULL); if (sdcard_cfg->root) { sdcard->root = strdup(sdcard_cfg->root); } else { sdcard->root = strdup("/sdcard"); } + AUDIO_MEM_CHECK(TAG, sdcard->root, { + free(sdcard); + return NULL; + }); + sdcard->card_detect_pin = sdcard_cfg->card_detect_pin; esp_periph_set_data(periph, sdcard); esp_periph_set_function(periph, _sdcard_init, _sdcard_run, _sdcard_destroy); diff --git a/components/esp_peripherals/periph_touch.c b/components/esp_peripherals/periph_touch.c index 53a451102..6c00a7027 100644 --- a/components/esp_peripherals/periph_touch.c +++ b/components/esp_peripherals/periph_touch.c @@ -48,10 +48,6 @@ static const char* TAG = "PERIPH_TOUCH"; return ret;\ } -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif - typedef struct periph_touch { esp_touch_handle_t touch; int touch_mask; @@ -123,9 +119,10 @@ static esp_err_t _touch_destroy(esp_periph_handle_t self) esp_periph_handle_t periph_touch_init(periph_touch_cfg_t* config) { esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_TOUCH, "periph_touch"); - mem_assert(periph); + AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_touch_t *periph_touch = calloc(1, sizeof(periph_touch_t)); - mem_assert(periph_touch); + + AUDIO_MEM_CHECK(TAG, periph_touch, return NULL); periph_touch->touch_mask = config->touch_mask; periph_touch->long_tap_time_ms = config->long_tap_time_ms; periph_touch->tap_threshold_percent = config->tap_threshold_percent; diff --git a/components/esp_peripherals/periph_wifi.c b/components/esp_peripherals/periph_wifi.c index b4a5066fc..24516e1d0 100644 --- a/components/esp_peripherals/periph_wifi.c +++ b/components/esp_peripherals/periph_wifi.c @@ -47,11 +47,7 @@ static const char *TAG = "PERIPH_WIFI"; return ret;\ } -#ifndef mem_assert -#define mem_assert(x) if (x == NULL) { ESP_LOGE(TAG, "Error alloc memory"); assert(x); } -#endif - -#define DEFAULT_RECONNECT_TIMEOUT_MS (5000) +#define DEFAULT_RECONNECT_TIMEOUT_MS (1000) typedef struct periph_wifi *periph_wifi_handle_t; @@ -307,16 +303,14 @@ static esp_err_t _wifi_init(esp_periph_handle_t self) static esp_err_t _wifi_destroy(esp_periph_handle_t self) { periph_wifi_handle_t periph_wifi = (periph_wifi_handle_t)esp_periph_get_data(self); + esp_periph_stop_timer(self); + periph_wifi->disable_auto_reconnect = true; esp_wifi_disconnect(); periph_wifi_wait_for_disconnected(self, portMAX_DELAY); esp_wifi_stop(); esp_wifi_deinit(); - if (periph_wifi->ssid) { - free(periph_wifi->ssid); - } - if (periph_wifi->password) { - free(periph_wifi->password); - } + free(periph_wifi->ssid); + free(periph_wifi->password); vEventGroupDelete(periph_wifi->state_event); free(periph_wifi); @@ -326,28 +320,36 @@ static esp_err_t _wifi_destroy(esp_periph_handle_t self) esp_periph_handle_t periph_wifi_init(periph_wifi_cfg_t *config) { - periph_wifi_handle_t periph_wifi = calloc(1, sizeof(struct periph_wifi)); - mem_assert(periph_wifi); + esp_periph_handle_t periph = NULL; + periph_wifi_handle_t periph_wifi = NULL; + bool _success = + ( + (periph = esp_periph_create(PERIPH_ID_WIFI, "periph_wifi")) && + (periph_wifi = calloc(1, sizeof(struct periph_wifi))) && + (periph_wifi->state_event = xEventGroupCreate()) && + (config->ssid ? (bool)(periph_wifi->ssid = strdup(config->ssid)) : true) && + (config->password ? (bool)(periph_wifi->password = strdup(config->password)) : true) + ); + + AUDIO_MEM_CHECK(TAG, _success, goto _periph_wifi_init_failed); - if (config->ssid) { - periph_wifi->ssid = strdup(config->ssid); - mem_assert(periph_wifi->ssid); - } - - if (config->password) { - periph_wifi->password = strdup(config->password); - mem_assert(periph_wifi->password); - } periph_wifi->reconnect_timeout_ms = config->reconnect_timeout_ms; if (periph_wifi->reconnect_timeout_ms == 0) { periph_wifi->reconnect_timeout_ms = DEFAULT_RECONNECT_TIMEOUT_MS; } periph_wifi->disable_auto_reconnect = config->disable_auto_reconnect; - periph_wifi->state_event = xEventGroupCreate(); - esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_WIFI, "periph_wifi"); - mem_assert(periph); + esp_periph_set_data(periph, periph_wifi); esp_periph_set_function(periph, _wifi_init, _wifi_run, _wifi_destroy); g_periph = periph; return periph; + +_periph_wifi_init_failed: + if (periph_wifi) { + vEventGroupDelete(periph_wifi->state_event); + free(periph_wifi->ssid); + free(periph_wifi->password); + free(periph_wifi); + } + return NULL; }