Skip to content

Commit

Permalink
audio refactoring done + T-WATCH2020 support
Browse files Browse the repository at this point in the history
  • Loading branch information
philippe44 committed Aug 3, 2020
1 parent 78563b2 commit 340a1bd
Show file tree
Hide file tree
Showing 16 changed files with 297 additions and 105 deletions.
2 changes: 2 additions & 0 deletions build-scripts/ESP32-A1S-sdkconfig.defaults
Expand Up @@ -31,6 +31,8 @@ CONFIG_SPDIF_BCK_IO=27
CONFIG_SPDIF_WS_IO=26
CONFIG_SPDIF_DO_IO=-1
CONFIG_DAC_CONFIG="model=AC101,bck=27,ws=26,do=25,di=35,sda=33,scl=32"
CONFIG_MUTE_GPIO=-1
CONFIG_MUTE_GPIO_LEVEL=-1
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

Expand Down
2 changes: 2 additions & 0 deletions build-scripts/I2S-4MFlash-sdkconfig.defaults
Expand Up @@ -33,6 +33,8 @@ CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=-1
CONFIG_MUTE_GPIO=-1
CONFIG_MUTE_GPIO_LEVEL=-1

CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"
Expand Down
3 changes: 2 additions & 1 deletion build-scripts/SqueezeAmp4MBFlash-sdkconfig.defaults
Expand Up @@ -31,9 +31,10 @@ CONFIG_BAT_SCALE="20.24"
CONFIG_I2S_NUM=0
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_CONFIG="bck=33,ws=25,do=15"
CONFIG_DAC_CONFIG="model=TAS57xx,bck=33,ws=25,do=32,sda=27,scl=26,mute=14"
CONFIG_DAC_CONFIG="model=TAS57xx,bck=33,ws=25,do=32,sda=27,scl=26,mute=14:0"
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"
CONFIG_MUTE_GPIO_LEVEL=-1

#
# SDK tool configuration
Expand Down
1 change: 1 addition & 0 deletions build-scripts/SqueezeAmp8MBFlash-sdkconfig.defaults
Expand Up @@ -32,6 +32,7 @@ CONFIG_I2S_NUM=0
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_CONFIG="bck=33,ws=25,do=15"
CONFIG_DAC_CONFIG="model=TAS57xx,bck=33,ws=25,do=32,sda=27,scl=26,mute=14"
CONFIG_MUTE_GPIO_LEVEL=-1

CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"
Expand Down
12 changes: 12 additions & 0 deletions components/config/config.c
Expand Up @@ -611,9 +611,21 @@ void config_delete_key(const char *key){
}
config_unlock();
}

void * config_alloc_get(nvs_type_t nvs_type, const char *key) {
return config_alloc_get_default(nvs_type, key, NULL, 0);
}

void * config_alloc_get_str(const char *key, char *lead, char *fallback) {
if (lead && *lead) return strdup(lead);
char *value = config_alloc_get_default(NVS_TYPE_STR, key, NULL, 0);
if ((!value || !*value) && fallback) {
if (value) free(value);
value = strdup(fallback);
}
return value;
}

void * config_alloc_get_default(nvs_type_t nvs_type, const char *key, void * default_value, size_t blob_size) {

void * value = NULL;
Expand Down
1 change: 1 addition & 0 deletions components/config/config.h
Expand Up @@ -34,6 +34,7 @@ void * config_alloc_get_default(nvs_type_t type, const char *key, void * default
void config_delete_key(const char *key);
void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
void * config_alloc_get(nvs_type_t nvs_type, const char *key) ;
void * config_alloc_get_str(const char *key, char *lead, char *fallback);
bool wait_for_commit();
char * config_alloc_get_json(bool bFormatted);
esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value);
Expand Down
7 changes: 1 addition & 6 deletions components/display/display.c
Expand Up @@ -56,12 +56,7 @@ GDS_DetectFunc *drivers[] = { SH1106_Detect, SSD1306_Detect, SSD132x_Detect, SSD
*/
void display_init(char *welcome) {
bool init = false;
char *config = config_alloc_get(NVS_TYPE_STR, "display_config");

if (!config) {
ESP_LOGI(TAG, "no display");
return;
}
char *config = config_alloc_get_str("display_config", CONFIG_DISPLAY_CONFIG, "N/A");

int width = -1, height = -1, backlight_pin = -1;
char *p, *drivername = strstr(config, "driver");
Expand Down
2 changes: 1 addition & 1 deletion components/services/accessors.c
Expand Up @@ -75,7 +75,7 @@ const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host) {
.quadhd_io_num = -1
};

nvs_item = config_alloc_get(NVS_TYPE_STR, "spi_config");
nvs_item = config_alloc_get_str("spi_config", CONFIG_SPI_CONFIG, NULL);
if (nvs_item) {
if ((p = strcasestr(nvs_item, "data")) != NULL) spi.mosi_io_num = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(nvs_item, "clk")) != NULL) spi.sclk_io_num = atoi(strchr(p, '=') + 1);
Expand Down
2 changes: 1 addition & 1 deletion components/services/led.c
Expand Up @@ -231,7 +231,7 @@ void led_svc_init(void) {
#ifndef CONFIG_LED_LOCKED
parse_set_GPIO(set_led_gpio);
#endif
ESP_LOGI(TAG,"Configuring LEDs green:%d (active:%d %d%%), red:%d (active:%d %d%%)", green.gpio, green.active, green.pwm, red.gpio, red.active, red.pwm);
ESP_LOGI(TAG,"Configuring LEDs green:%d (active:%d %d%%), red:%d (active:%d %d%%)", green.gpio, green.active, green.pwm, green.gpio, green.active, green.pwm );

char *nvs_item = config_alloc_get(NVS_TYPE_STR, "led_brightness"), *p;
if (nvs_item) {
Expand Down
5 changes: 3 additions & 2 deletions components/squeezelite/ac101/ac101.c
Expand Up @@ -52,7 +52,7 @@ static bool init(char *config, int i2c_port_num);
static void deinit(void);
static void speaker(bool active);
static void headset(bool active);
static void volume(unsigned left, unsigned right);
static bool volume(unsigned left, unsigned right);
static void power(adac_power_e mode);

const struct adac_s dac_ac101 = { "AC101", init, deinit, power, speaker, headset, volume };
Expand Down Expand Up @@ -164,8 +164,9 @@ static void deinit(void) {
/****************************************************************************************
* change volume
*/
static void volume(unsigned left, unsigned right) {
static bool volume(unsigned left, unsigned right) {
// nothing at that point, volume is handled by backend
return false;
}

/****************************************************************************************
Expand Down
2 changes: 1 addition & 1 deletion components/squeezelite/adac.h
Expand Up @@ -21,7 +21,7 @@ struct adac_s {
void (*power)(adac_power_e mode);
void (*speaker)(bool active);
void (*headset)(bool active);
void (*volume)(unsigned left, unsigned right);
bool (*volume)(unsigned left, unsigned right);
};

extern const struct adac_s dac_tas57xx;
Expand Down
155 changes: 148 additions & 7 deletions components/squeezelite/external/dac_external.c
Expand Up @@ -12,22 +12,163 @@
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <driver/i2s.h>
#include "driver/i2c.h"
#include "esp_log.h"
#include "cJSON.h"
#include "config.h"
#include "adac.h"

static const char TAG[] = "DAC external";

static void deinit(void) { }
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);
static void deinit(void) { };
static void speaker(bool active) { };
static void headset(bool active) { } ;
static void volume(unsigned left, unsigned right) { };
static void power(adac_power_e mode) { };

static bool i2c_json_execute(char *set);
static esp_err_t i2c_write_reg(uint8_t reg, uint8_t val);
static uint8_t i2c_read_reg(uint8_t reg);

const struct adac_s dac_external = { "i2s", init, deinit, power, speaker, headset, volume };
static int i2c_port, i2c_addr;
static cJSON *i2c_json;

/****************************************************************************************
* init
*/
static bool init(char *config, int i2c_port_num) {
char *p;
i2c_port = i2c_port_num;

// configure i2c
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = -1,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = -1,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 250000,
};

if ((p = strcasestr(config, "i2c")) != NULL) i2c_addr = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "sda")) != NULL) i2c_config.sda_io_num = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "scl")) != NULL) i2c_config.scl_io_num = atoi(strchr(p, '=') + 1);

p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL);
i2c_json = cJSON_Parse(p);

if (!i2c_addr || !i2c_json || i2c_config.sda_io_num == -1 || i2c_config.scl_io_num == -1) {
if (p) free(p);
ESP_LOGW(TAG, "No i2c controlset found");
return true;
}

ESP_LOGI(TAG, "DAC uses I2C @%d with sda:%d, scl:%d", i2c_addr, i2c_config.sda_io_num, i2c_config.scl_io_num);

// we have an I2C configured
i2c_param_config(i2c_port, &i2c_config);
i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);

if (!i2c_json_execute("init")) {
ESP_LOGE(TAG, "could not intialize DAC");
return false;
}

return true;
}

static bool init(char *config, int i2c_port_num) {
return true;
/****************************************************************************************
* power
*/
static void power(adac_power_e mode) {
if (mode == ADAC_STANDBY || mode == ADAC_OFF) i2c_json_execute("poweroff");
else i2c_json_execute("poweron");
}

/****************************************************************************************
*
*/
bool i2c_json_execute(char *set) {
cJSON *json_set = cJSON_GetObjectItemCaseSensitive(i2c_json, set);
cJSON *item;

if (!json_set) return true;

cJSON_ArrayForEach(item, json_set)
{
cJSON *reg = cJSON_GetObjectItemCaseSensitive(item, "reg");
cJSON *val = cJSON_GetObjectItemCaseSensitive(item, "val");
cJSON *mode = cJSON_GetObjectItemCaseSensitive(item, "mode");

if (!reg || !val) continue;

if (!mode) {
i2c_write_reg(reg->valueint, val->valueint);
} else if (!strcasecmp(mode->valuestring, "or")) {
uint8_t data = i2c_read_reg(reg->valueint);
data |= (uint8_t) val->valueint;
i2c_write_reg(reg->valueint, data);
} else if (!strcasecmp(mode->valuestring, "and")) {
uint8_t data = i2c_read_reg(reg->valueint);
data &= (uint8_t) val->valueint;
i2c_write_reg(reg->valueint, data);
}
}

return true;
}

/****************************************************************************************
*
*/
static esp_err_t i2c_write_reg(uint8_t reg, uint8_t val) {
esp_err_t ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);

i2c_master_write_byte(cmd, i2c_addr | I2C_MASTER_WRITE, I2C_MASTER_NACK);
i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
i2c_master_write_byte(cmd, val, I2C_MASTER_NACK);

i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

if (ret != ESP_OK) {
ESP_LOGW(TAG, "I2C write failed");
}

return ret;
}

/****************************************************************************************
*
*/
static uint8_t i2c_read_reg(uint8_t reg) {
esp_err_t ret;
uint8_t data = 0;

i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);

i2c_master_write_byte(cmd, i2c_addr | I2C_MASTER_WRITE, I2C_MASTER_NACK);
i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);

i2c_master_start(cmd);
i2c_master_write_byte(cmd, i2c_addr | I2C_MASTER_READ, I2C_MASTER_NACK);
i2c_master_read_byte(cmd, &data, I2C_MASTER_NACK);

i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

if (ret != ESP_OK) {
ESP_LOGW(TAG, "I2C read failed");
}

return data;
}


0 comments on commit 340a1bd

Please sign in to comment.