Merge branch 'master-v4.3' into led_visu-v4.3

This commit is contained in:
wizmo2
2023-06-16 20:00:26 -04:00
committed by GitHub
277 changed files with 9302 additions and 16032 deletions

View File

@@ -1,3 +1,8 @@
# for the forgetful, REQUIRES cannot use CONFIG_XXX due to parsing order
if(IDF_TARGET STREQUAL "esp32")
set(target_requires "driver_bt")
endif()
idf_component_register( SRC_DIRS . external ac101 tas57xx wm8978
INCLUDE_DIRS . ac101
PRIV_REQUIRES
@@ -6,7 +11,6 @@ idf_component_register( SRC_DIRS . external ac101 tas57xx wm8978
esp_common
esp-dsp
platform_config
driver_bt
services
spotify
raop
@@ -15,6 +19,7 @@ idf_component_register( SRC_DIRS . external ac101 tas57xx wm8978
audio
led_strip
_override
${target_requires}
EMBED_FILES vu_s.data arrow.data
)

View File

@@ -48,7 +48,7 @@ static const char TAG[] = "AC101";
return b;\
}
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config);
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config, bool *mck);
static void speaker(bool active);
static void headset(bool active);
static bool volume(unsigned left, unsigned right);
@@ -64,7 +64,7 @@ static void ac101_set_spk_volume(uint8_t volume);
/****************************************************************************************
* init
*/
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config, bool *mck) {
adac_init(config, i2c_port);
if (adac_read_word(AC101_ADDR, CHIP_AUDIO_RS) == 0xffff) {
ESP_LOGW(TAG, "No AC101 detected");

View File

@@ -17,7 +17,7 @@ typedef enum { ADAC_ON = 0, ADAC_STANDBY, ADAC_OFF } adac_power_e;
struct adac_s {
char *model;
bool (*init)(char *config, int i2c_port_num, i2s_config_t *i2s_config);
bool (*init)(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck);
void (*deinit)(void);
void (*power)(adac_power_e mode);
void (*speaker)(bool active);

View File

@@ -29,16 +29,8 @@ static int i2c_port = -1;
* init
*/
int adac_init(char *config, int i2c_port_num) {
char *p;
int i2c_addr = 0;
// some crappy codecs require MCLK to work
if ((p = strcasestr(config, "mck")) != NULL) {
ESP_LOGI(TAG, "Configuring MCLK on GPIO0");
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
REG_WRITE(PIN_CTRL, 0xFFFFFFF0);
}
i2c_port = i2c_port_num;
// configure i2c

View File

@@ -406,7 +406,7 @@ static bool cspot_cmd_handler(cspot_event_t cmd, va_list args)
case CSPOT_VOLUME: {
u32_t volume = va_arg(args, u32_t);
LOG_INFO("CSpot volume %u", volume);
volume = 65536 * powf(volume / 65536.0f, 2);
volume = 65536 * powf(volume / 65536.0f, 4);
set_volume(volume, volume);
break;
default:

View File

@@ -24,7 +24,7 @@ static void speaker(bool active);
static void headset(bool active);
static bool volume(unsigned left, unsigned right) { return false; }
static void power(adac_power_e mode);
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck);
static bool i2c_json_execute(char *set);
@@ -56,7 +56,7 @@ static struct {
/****************************************************************************************
* init
*/
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck) {
char *p;
i2c_addr = adac_init(config, i2c_port_num);
@@ -71,11 +71,7 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
int i;
sscanf(p, "%*[^=]=%31[^,]", model);
for (i = 0; *model && ((p = codecs[i].controlset) != NULL) && strcasecmp(codecs[i].model, model); i++);
if (p && codecs[i].mclk) {
ESP_LOGI(TAG, "Configuring MCLK on GPIO0");
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
REG_WRITE(PIN_CTRL, 0xFFFFFFF0);
}
if (p) *mck = codecs[i].mclk;
}
i2c_json = cJSON_Parse(p);

View File

@@ -152,9 +152,9 @@ static int get_opus_packet(void) {
if (status) OG(&go, stream_pagein, &u->state, &u->page);
}
// only return a negative value when end of streaming is reached
// only return a negative value when true end of streaming is reached
if (status > 0) packet = status;
else if (stream.state > DISCONNECT) packet = 0;
else if (stream.state > DISCONNECT || _buf_used(streambuf)) packet = 0;
UNLOCK_S;
return packet;

View File

@@ -190,10 +190,14 @@ static void set_amp_gpio(int gpio, char *value) {
* Set pin from config string
*/
static void set_i2s_pin(char *config, i2s_pin_config_t *pin_config) {
pin_config->bck_io_num = pin_config->ws_io_num = pin_config->data_out_num = pin_config->data_in_num = -1;
pin_config->bck_io_num = pin_config->ws_io_num = pin_config->data_out_num = pin_config->data_in_num = -1;
PARSE_PARAM(config, "bck", '=', pin_config->bck_io_num);
PARSE_PARAM(config, "ws", '=', pin_config->ws_io_num);
PARSE_PARAM(config, "do", '=', pin_config->data_out_num);
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
pin_config->mck_io_num = strcasestr(config, "mck") ? 0 : -1;
PARSE_PARAM(config, "mck", '=', pin_config->mck_io_num);
#endif
}
/****************************************************************************************
@@ -234,14 +238,19 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
",ws=" STR(CONFIG_SPDIF_WS_IO) ",do=" STR(CONFIG_SPDIF_DO_IO));
char *dac_config = config_alloc_get_str("dac_config", CONFIG_DAC_CONFIG, "model=i2s,bck=" STR(CONFIG_I2S_BCK_IO)
",ws=" STR(CONFIG_I2S_WS_IO) ",do=" STR(CONFIG_I2S_DO_IO)
",ws=" STR(CONFIG_I2S_WS_IO) ",do=" STR(CONFIG_I2S_DO_IO) ",mck=" STR(CONFIG_I2S_MCK_IO)
",sda=" STR(CONFIG_I2C_SDA) ",scl=" STR(CONFIG_I2C_SCL)
",mute=" STR(CONFIG_MUTE_GPIO));
i2s_pin_config_t i2s_dac_pin, i2s_spdif_pin;
i2s_pin_config_t i2s_dac_pin, i2s_spdif_pin;
set_i2s_pin(spdif_config, &i2s_spdif_pin);
set_i2s_pin(dac_config, &i2s_dac_pin);
if (i2s_dac_pin.data_out_num == -1 && i2s_spdif_pin.data_out_num == -1) {
LOG_WARN("DAC and SPDIF not configured, NOT launching i2s thread");
return;
}
/* BEWARE: i2s.c must be patched otherwise L/R are swapped in 32 bits mode */
// common I2S initialization
@@ -250,7 +259,9 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
// in case of overflow, do not replay old buffer
i2s_config.tx_desc_auto_clear = true;
i2s_config.use_apll = true;
#ifndef CONFIG_IDF_TARGET_ESP32S3
i2s_config.use_apll = true;
#endif
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1; //Interrupt level 1
if (strcasestr(device, "spdif")) {
@@ -272,8 +283,8 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
i2s_config.dma_buf_count = DMA_BUF_COUNT * 2;
/*
In DMA, we have room for (LEN * COUNT) frames of 32 bits samples that
we push at sample_rate * 2. Each of these peuso-frames is a single true
audio frame. So the real depth is true frames is (LEN * COUNT / 2)
we push at sample_rate * 2. Each of these pseudo-frames is a single true
audio frame. So the real depth in true frames is (LEN * COUNT / 2)
*/
dma_buf_frames = DMA_BUF_COUNT * DMA_BUF_LEN / 2;
@@ -303,12 +314,36 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
if ((p = strchr(mute, ':')) != NULL) mute_control.active = atoi(p + 1);
}
bool mck_required = false;
for (int i = 0; adac == &dac_external && dac_set[i]; i++) if (strcasestr(dac_set[i]->model, model)) adac = dac_set[i];
res = adac->init(dac_config, I2C_PORT, &i2s_config) ? ESP_OK : ESP_FAIL;
res = adac->init(dac_config, I2C_PORT, &i2s_config, &mck_required) ? ESP_OK : ESP_FAIL;
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 0)
int mck_io_num = strcasestr(dac_config, "mck") || mck_required ? 0 : -1;
PARSE_PARAM(dac_config, "mck", '=', mck_io_num);
LOG_INFO("configuring MCLK on GPIO %d", mck_io_num);
if (mck_io_num == GPIO_NUM_0) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
WRITE_PERI_REG(PIN_CTRL, CONFIG_I2S_NUM == I2S_NUM_0 ? 0xFFF0 : 0xFFFF);
} else if (mck_io_num == GPIO_NUM_1) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3);
WRITE_PERI_REG(PIN_CTRL, CONFIG_I2S_NUM == I2S_NUM_0 ? 0xF0F0 : 0xF0FF);
} else if (mck_io_num == GPIO_NUM_2) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2);
WRITE_PERI_REG(PIN_CTRL, CONFIG_I2S_NUM == I2S_NUM_0 ? 0xFF00 : 0xFF0F);
} else {
LOG_WARN("invalid MCK gpio %d", mck_io_num);
}
#else
if (mck_required && i2s_dac_pin.mck_io_num == -1) i2s_dac_pin.mck_io_num = 0;
LOG_INFO("configuring MCLK on GPIO %d", i2s_dac_pin.mck_io_num);
#endif
res |= i2s_driver_install(CONFIG_I2S_NUM, &i2s_config, 0, NULL);
res |= i2s_set_pin(CONFIG_I2S_NUM, &i2s_dac_pin);
if (res == ESP_OK && mute_control.gpio >= 0) {
gpio_pad_select_gpio(mute_control.gpio);
gpio_set_direction(mute_control.gpio, GPIO_MODE_OUTPUT);
@@ -366,7 +401,7 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
// create task as a FreeRTOS task but uses stack in internal RAM
{
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
static DRAM_ATTR StackType_t xStack[OUTPUT_THREAD_STACK_SIZE] __attribute__ ((aligned (4)));
static EXT_RAM_ATTR StackType_t xStack[OUTPUT_THREAD_STACK_SIZE] __attribute__ ((aligned (4)));
output_i2s_task = xTaskCreateStaticPinnedToCore( (TaskFunction_t) output_thread_i2s, "output_i2s", OUTPUT_THREAD_STACK_SIZE,
NULL, CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT + 1, xStack, &xTaskBuffer, 0 );
}

View File

@@ -99,7 +99,7 @@ static char *new_server_cap;
static char player_name[PLAYER_NAME_LEN + 1] = "";
static const char *name_file = NULL;
void send_packet(u8_t *packet, size_t len) {
void slimproto_send_packet(u8_t *packet, size_t len) {
u8_t *ptr = packet;
unsigned try = 0;
ssize_t n;

View File

@@ -559,7 +559,8 @@ void buf_destroy(struct buffer *buf);
void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate);
void slimproto_stop(void);
void wake_controller(void);
void send_packet(u8_t *packet, size_t len);
void slimproto_send_packet(u8_t *packet, size_t len);
#define send_packet(p, s) slimproto_send_packet(p,s)
// stream.c
typedef enum { STOPPED = 0, DISCONNECT, STREAMING_WAIT,

View File

@@ -39,7 +39,7 @@
static const char TAG[] = "TAS5713";
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck);
static void speaker(bool active) { };
static void headset(bool active) { } ;
static bool volume(unsigned left, unsigned right);
@@ -65,7 +65,7 @@ typedef enum {
/****************************************************************************************
* init
*/
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config, bool *mck) {
/* find if there is a tas5713 attached. Reg 0 should read non-zero but not 255 if so */
adac_init(config, i2c_port);
if (adac_read_byte(TAS5713, 0x00) == 255) {

View File

@@ -23,7 +23,7 @@
static const char TAG[] = "TAS575x/8x";
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck);
static void speaker(bool active);
static void headset(bool active);
static bool volume(unsigned left, unsigned right);
@@ -71,7 +71,7 @@ static int tas57_detect(void);
/****************************************************************************************
* init
*/
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config, bool *mck) {
// find which TAS we are using (if any)
tas57_addr = adac_init(config, i2c_port);
if (!tas57_addr) tas57_addr = tas57_detect();

View File

@@ -152,9 +152,9 @@ static int get_ogg_packet(void) {
if (status) OG(&go, stream_pagein, &v->state, &v->page);
}
// only return a negative value when end of streaming is reached
// only return a negative value when true end of streaming is reached
if (status > 0) packet = status;
else if (stream.state > DISCONNECT) packet = 0;
else if (stream.state > DISCONNECT || _buf_used(streambuf)) packet = 0;
UNLOCK_S;
return packet;

View File

@@ -23,7 +23,7 @@ static void speaker(bool active) { }
static void headset(bool active) { }
static bool volume(unsigned left, unsigned right) { return false; }
static void power(adac_power_e mode);
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config, bool *mck);
static esp_err_t i2c_write_shadow(uint8_t reg, uint16_t val);
static uint16_t i2c_read_shadow(uint8_t reg);
@@ -47,12 +47,14 @@ static uint16_t WM8978_REGVAL_TBL[58] = {
/****************************************************************************************
* init
*/
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
static bool init(char *config, int i2c_port, i2s_config_t *i2s_config, bool *mck) {
WM8978 = adac_init(config, i2c_port);
if (!WM8978) WM8978 = 0x1a;
ESP_LOGI(TAG, "WM8978 detected @%d", WM8978);
*mck = true;
// init sequence
i2c_write_shadow(0, 0);
i2c_write_shadow(4, 16);
@@ -61,11 +63,6 @@ static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {
i2c_write_shadow(43, 16);
i2c_write_shadow(49, 102);
// Configure system clk to GPIO0 for DAC MCLK input
ESP_LOGI(TAG, "Configuring MCLK on GPIO0");
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
REG_WRITE(PIN_CTRL, 0xFFFFFFF0);
return true;
}