Compare commits

...

4 Commits

Author SHA1 Message Date
Sebastien
3e74292fc0 Reposition audio config and other small fixes - release 2020-10-09 16:35:30 -04:00
Sebastien
b301376fc6 Fix update page - release
Pressing check for update no longer appends duplicate entries in the branch selection drop down
2020-10-09 06:51:32 -04:00
Sebastien
262f5ff3e7 Merge remote-tracking branch 'origin/master-cmake' into master-cmake 2020-10-09 06:46:15 -04:00
Sebastien
d379858dd2 Display config UI fixes - release
Add 2 entries as a replacement for the ST77xx driver name, remove SSD1306 default.
2020-10-08 21:09:36 -04:00
13 changed files with 149 additions and 60 deletions

View File

@@ -52,7 +52,8 @@ static const char *known_drivers[] = {"SH1106",
"SSD1327",
"SSD1675",
"SSD1351",
"ST77xx",
"ST7735",
"ST7789",
"ILI9341",
NULL
};

View File

@@ -22,6 +22,7 @@
const char * desc_squeezelite ="Squeezelite Options";
const char * desc_dac= "DAC Options";
const char * desc_spdif= "SPDIF Options";
const char * desc_audio= "General Audio Options";
#define CODECS_BASE "flac,pcm,mp3,ogg"
@@ -69,6 +70,10 @@ static struct {
struct arg_lit *clear;
struct arg_end *end;
} spdif_args;
static struct {
struct arg_str *jack_behavior;
struct arg_end *end;
} audio_args;
static struct {
struct arg_str * server; // -s <server>[:<port>]\tConnect to specified server, otherwise uses autodiscovery to find server\n"
struct arg_str * buffers;// " -b <stream>:<output>\tSpecify internal Stream and Output buffer sizes in Kbytes\n"
@@ -137,8 +142,53 @@ int check_missing_parm(struct arg_int * int_parm, FILE * f){
}
return res;
}
static int do_audio_cmd(int argc, char **argv){
esp_err_t err=ESP_OK;
int nerrors = arg_parse(argc, argv,(void **)&audio_args);
char *buf = NULL;
size_t buf_size = 0;
FILE *f = open_memstream(&buf, &buf_size);
if (f == NULL) {
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
return 1;
}
if(nerrors >0){
arg_print_errors(f,audio_args.end,desc_audio);
return 1;
}
if(audio_args.jack_behavior->count>0){
err = ESP_OK; // suppress any error code that might have happened in a previous step
if(strcasecmp(audio_args.jack_behavior->sval[0],"Headphones")){
err = config_set_value(NVS_TYPE_STR, "jack_mutes_amp", "y");
}
else if(strcasecmp(audio_args.jack_behavior->sval[0],"Subwoofer")){
err = config_set_value(NVS_TYPE_STR, "jack_mutes_amp", "n");
}
else {
nerrors++;
fprintf(f,"Unknown Audio Jack Behavior %s.\n",audio_args.jack_behavior->sval[0]);
}
if(err!=ESP_OK){
nerrors++;
fprintf(f,"Error setting Audio Jack Behavior %s. %s\n",audio_args.jack_behavior->sval[0], esp_err_to_name(err));
}
else {
fprintf(f,"Audio Jack Behavior changed to %s\n",audio_args.jack_behavior->sval[0]);
}
}
if(!nerrors ){
fprintf(f,"Done.\n");
}
fflush (f);
cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf);
fclose(f);
FREE_AND_NULL(buf);
return (nerrors==0 && err==ESP_OK)?0:1;
}
static int do_spdif_cmd(int argc, char **argv){
i2s_platform_config_t i2s_dac_pin = {
.i2c_addr = -1,
@@ -154,7 +204,7 @@ static int do_spdif_cmd(int argc, char **argv){
esp_err_t err=ESP_OK;
int nerrors = arg_parse(argc, argv,(void **)&spdif_args);
if (spdif_args.clear->count) {
cmd_send_messaging(argv[0],MESSAGING_WARNING,"SPDIF config cleared");
cmd_send_messaging(argv[0],MESSAGING_WARNING,"SPDIF config cleared\n");
config_set_value(NVS_TYPE_STR, "spdif_config", "");
return 0;
}
@@ -163,7 +213,7 @@ static int do_spdif_cmd(int argc, char **argv){
size_t buf_size = 0;
FILE *f = open_memstream(&buf, &buf_size);
if (f == NULL) {
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.");
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
return 1;
}
if(nerrors >0){
@@ -205,7 +255,7 @@ static int do_i2s_cmd(int argc, char **argv)
esp_err_t err=ESP_OK;
int nerrors = arg_parse(argc, argv,(void **)&i2s_args);
if (i2s_args.clear->count) {
cmd_send_messaging(argv[0],MESSAGING_WARNING,"DAC config cleared");
cmd_send_messaging(argv[0],MESSAGING_WARNING,"DAC config cleared\n");
config_set_value(NVS_TYPE_STR, "dac_config", "");
return 0;
}
@@ -214,7 +264,7 @@ static int do_i2s_cmd(int argc, char **argv)
size_t buf_size = 0;
FILE *f = open_memstream(&buf, &buf_size);
if (f == NULL) {
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.");
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
return 1;
}
if(nerrors >0){
@@ -329,6 +379,15 @@ cJSON * spdif_cb(){
return values;
}
cJSON * audio_cb(){
cJSON * values = cJSON_CreateObject();
char * p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
cJSON_AddBoolToObject(values,"jack_behavior",(strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0));
FREE_AND_NULL(p);
return values;
}
void get_str_parm_json(struct arg_str * parm, cJSON * entry){
const char * name = parm->hdr.longopts?parm->hdr.longopts:parm->hdr.glossary;
if(parm->count>0){
@@ -360,7 +419,7 @@ static int do_squeezelite_cmd(int argc, char **argv)
size_t buf_size = 0;
FILE *f = open_memstream(&buf, &buf_size);
if (f == NULL) {
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.");
cmd_send_messaging(argv[0],MESSAGING_ERROR,"Unable to open memory stream.\n");
return 1;
}
fprintf(f,"Not yet implemented!");
@@ -468,7 +527,21 @@ static void register_i2s_config(void){
cmd_to_json_with_cb(&cmd,&i2s_cb);
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
static void register_spdif_config(void){
static void register_audio_config(void){
audio_args.jack_behavior = arg_str0("j", "jack_behavior","Headphones|Subwoofer","On supported DAC, determines the audio jack behavior. Selecting headphones will cause the external amp to be muted on insert, while selecting Subwoofer will keep the amp active all the time.");
audio_args.end = arg_end(6);
const esp_console_cmd_t cmd = {
.command = CFG_TYPE_AUDIO("general"),
.help = desc_audio,
.hint = NULL,
.func = &do_audio_cmd,
.argtable = &audio_args
};
cmd_to_json_with_cb(&cmd,&audio_cb);
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}static void register_spdif_config(void){
spdif_args.clear = arg_lit0(NULL, "clear", "Clear configuration");
spdif_args.clock = arg_int1(NULL,"clock","<n>","Clock GPIO. e.g. 33");
spdif_args.wordselect = arg_int1(NULL,"wordselect","<n>","Word Select GPIO. e.g. 25");
@@ -517,7 +590,7 @@ static void register_squeezelite_config(void){
squeezelite_args.rate = arg_int0("Z","max_rate", "<n>", "Report rate to server in helo as the maximum sample rate we can support");
squeezelite_args.end = arg_end(6);
const esp_console_cmd_t cmd = {
.command = CFG_TYPE_SYST("squeezelite"),
.command = CFG_TYPE_AUDIO("squeezelite"),
.help = desc_squeezelite,
.hint = NULL,
.func = &do_squeezelite_cmd,
@@ -528,6 +601,7 @@ static void register_squeezelite_config(void){
}
void register_config_cmd(void){
register_audio_config();
register_squeezelite_config();
register_i2s_config();
register_spdif_config();

View File

@@ -365,7 +365,7 @@ static int do_i2c_set_display(int argc, char **argv)
config.speed = 8000000;
}
/* Check "--cs" option */
nerrors +=is_output_gpio(i2cdisp_args.cs,f,&config.CS_pin, true);
nerrors +=is_output_gpio(i2cdisp_args.cs,f,&config.CS_pin, false);
}
nerrors +=is_output_gpio(i2cdisp_args.reset,f,&config.RST_pin, false);
@@ -382,15 +382,12 @@ static int do_i2c_set_display(int argc, char **argv)
if (i2cdisp_args.driver->count) {
config.drivername=display_conf_get_driver_name(i2cdisp_args.driver->sval[0]) ;
}
else {
config.drivername = display_conf_get_driver_name("SSD1306");
}
if(i2cdisp_args.depth->count > 0 && strcasecmp(config.drivername,"SSD1326")==0) {
config.depth = i2cdisp_args.depth->ival[0];
}
/* Check "--back" option */
nerrors +=is_output_gpio(i2cdisp_args.back,f,&config.back, false);
if(!display_is_valid_driver(config.drivername)){
if(!config.drivername || !display_is_valid_driver(config.drivername)){
fprintf(f,"Unsupported display driver %s\n",config.drivername);
nerrors++;
}
@@ -905,7 +902,7 @@ static void register_i2c_set_display(){
i2cdisp_args.reset = arg_int0(NULL, "reset", "<n>", "Reset GPIO");
i2cdisp_args.hflip = arg_lit0(NULL, "hf", "Flip horizontally");
i2cdisp_args.vflip = arg_lit0(NULL, "vf", "Flip vertically");
i2cdisp_args.driver = arg_str0("d", "driver", supported_drivers?supported_drivers:"<string>", "Driver (default SSD1306)");
i2cdisp_args.driver = arg_str0("d", "driver", supported_drivers?supported_drivers:"<string>", "Driver");
i2cdisp_args.cs = arg_int0("b", "cs", "<n>","SPI Only. CS GPIO (for SPI displays)");
i2cdisp_args.speed = arg_int0("s", "speed", "<n>","SPI Only. Bus Speed (Default 8000000). SPI interface can work up to 26MHz~40MHz");
i2cdisp_args.back = arg_int0("b", "back", "<n>","Backlight GPIO (if applicable)");

View File

@@ -1,7 +1,7 @@
/* Console example — various system commands
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
@@ -50,7 +50,7 @@ static struct {
struct arg_str *telnet;
#if WITH_TASKS_INFO
struct arg_lit *stats;
#endif
#endif
struct arg_end *end;
} set_services_args;
static const char * TAG = "cmd_system";
@@ -127,30 +127,30 @@ static void register_version()
esp_err_t guided_boot(esp_partition_subtype_t partition_subtype)
{
if(is_recovery_running){
if(partition_subtype ==ESP_PARTITION_SUBTYPE_APP_FACTORY){
log_send_messaging(MESSAGING_WARNING,"RECOVERY application is already active");
if(!wait_for_commit()){
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
}
vTaskDelay(750/ portTICK_PERIOD_MS);
esp_restart();
return ESP_OK;
}
}
else {
if(partition_subtype !=ESP_PARTITION_SUBTYPE_APP_FACTORY){
log_send_messaging(MESSAGING_WARNING,"SQUEEZELITE application is already active");
if(!wait_for_commit()){
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
}
vTaskDelay(750/ portTICK_PERIOD_MS);
esp_restart();
return ESP_OK;
}
}
if(is_recovery_running){
if(partition_subtype ==ESP_PARTITION_SUBTYPE_APP_FACTORY){
log_send_messaging(MESSAGING_WARNING,"RECOVERY application is already active");
if(!wait_for_commit()){
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
}
vTaskDelay(750/ portTICK_PERIOD_MS);
esp_restart();
return ESP_OK;
}
}
else {
if(partition_subtype !=ESP_PARTITION_SUBTYPE_APP_FACTORY){
log_send_messaging(MESSAGING_WARNING,"SQUEEZELITE application is already active");
if(!wait_for_commit()){
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
}
vTaskDelay(750/ portTICK_PERIOD_MS);
esp_restart();
return ESP_OK;
}
}
esp_err_t err = ESP_OK;
bool bFound=false;
log_send_messaging(MESSAGING_INFO, "Looking for partition type %u",partition_subtype);
@@ -174,9 +174,7 @@ else {
log_send_messaging(MESSAGING_ERROR,"Unable to select partition for reboot: %s",esp_err_to_name(err));
}
else{
log_send_messaging(MESSAGING_WARNING, "Application partition %s sub type %u is selected for boot", partition->label,partition_subtype);
bFound=true;
messaging_post_message(MESSAGING_WARNING,MESSAGING_CLASS_SYSTEM,"Reboot failed. Cannot iterate through partitions");
bFound=true;
}
}
else
@@ -187,9 +185,8 @@ else {
ESP_LOGD(TAG, "Yielding to other processes");
taskYIELD();
if(bFound) {
log_send_messaging(MESSAGING_WARNING,"Configuration %s changes. ",config_has_changes()?"has":"does not have");
if(!wait_for_commit()){
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration. ");
log_send_messaging(MESSAGING_WARNING,"Unable to commit configuration changes. ");
}
vTaskDelay(750/ portTICK_PERIOD_MS);
esp_restart();

View File

@@ -14,6 +14,7 @@
extern "C" {
#endif
#define CFG_TYPE_HW(a) "cfg-hw-" a
#define CFG_TYPE_AUDIO(a) "cfg-audio-" a
#define CFG_TYPE_SYST(a) "cfg-syst-" a
#define CFG_TYPE_FW(a) "cfg-fw-" a
#define CFG_TYPE_GEN(a) "cfg-gen-" a

View File

@@ -343,7 +343,6 @@ const display_config_t * config_display_get(){
dstruct.drivername = display_conf_get_driver_name(strchr(p, '=') + 1);
}
dstruct.drivername=dstruct.drivername?dstruct.drivername:"SSD1306";
if ((p = strcasestr(config, "width")) != NULL) dstruct.width = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "height")) != NULL) dstruct.height = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "reset")) != NULL) dstruct.RST_pin = atoi(strchr(p, '=') + 1);

View File

@@ -178,6 +178,9 @@ static void set_jack_gpio(int gpio, char *value) {
jack.gpio = gpio;
if ((p = strchr(value, ':')) != NULL) jack.active = atoi(p + 1);
}
else {
jack.gpio = -1;
}
}
#endif
@@ -191,6 +194,9 @@ static void set_spkfault_gpio(int gpio, char *value) {
spkfault.gpio = gpio;
if ((p = strchr(value, ':')) != NULL) spkfault.active = atoi(p + 1);
}
else {
spkfault.gpio = -1;
}
}
#endif

View File

@@ -2,7 +2,7 @@ idf_component_register( SRC_DIRS .
INCLUDE_DIRS . ${IDF_PATH}/components/esp_http_server/src ${IDF_PATH}/components/esp_http_server/src/port/esp32 ${IDF_PATH}/components/esp_http_server/src/util ${IDF_PATH}/components/esp_http_server/src/
REQUIRES squeezelite-ota json mdns
PRIV_REQUIRES tools services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console
EMBED_FILES res/style.css.gz res/code.js.gz index.html res/bootstrap.css.gz res/jquery.js.gz res/bootstrap.js.gz res/favicon.ico
EMBED_FILES res/style.css.gz res/code.js.gz index.html res/bootstrap.css.gz res/yeti/bootstrap.css.gz res/jquery.js.gz res/bootstrap.js.gz res/favicon.ico
)

View File

@@ -201,7 +201,7 @@
<div class="tab-pane fade mt-2" id="tab-configuration">
<ul class="nav nav-tabs bg-info" name="secnav">
<li class="nav-link" style="padding: inherit; border: none;">
<a class="nav-link active" data-toggle="tab" href="#tab-audio">Audio + LMS</a>
<a class="nav-link active" data-toggle="tab" href="#tab-cfg-audio">Audio</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#tab-cfg-syst">System</a>
@@ -295,13 +295,13 @@
</div>
</div>
<div class="tab-pane fade active show" id="tab-audio">
<div class="tab-pane fade active show" id="tab-cfg-audio">
<div class="card text-white bg-primary mb-3">
<div class="card-header">Command Line Templates</div>
<div class="card-header">Usage Templates</div>
<div class="card-body">
<fieldset >
<fieldset class="form-group" id="output-tmpl">
<legend>Audio Output</legend>
<legend>Output</legend>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="output-tmpl" id="i2s" >

File diff suppressed because one or more lines are too long

View File

@@ -72,6 +72,16 @@ var escapeHTML = function(unsafe) {
}
});
};
function setNavColor(stylename){
$('[name=secnav]').removeClass('bg-secondary bg-warning');
$("footer.footer").removeClass('bg-secondary bg-warning');
$("#mainnav").removeClass('bg-secondary bg-warning');
if(stylename.length>0){
$('[name=secnav]').addClass(stylename);
$("footer.footer").addClass(stylename);
$("#mainnav").addClass(stylename);
}
}
function handleTemplateTypeRadio(outtype){
if (outtype == 'bt') {
$("#btsinkdiv").parent().show(200);
@@ -103,6 +113,7 @@ function handleTemplateTypeRadio(outtype){
function handleExceptionResponse(xhr, ajaxOptions, thrownError){
console.log(xhr.status);
console.log(thrownError);
enableStatusTimer=true;
if (thrownError != '') showLocalMessage(thrownError, 'MESSAGING_ERROR');
}
function HideCmdMessage(cmdname){
@@ -278,13 +289,15 @@ function onChooseFile(event, onLoadFileHandler) {
function delay_reboot(duration,cmdname, ota=false){
url= (ota?'/reboot_ota.json':'/reboot.json');
$("tbody#tasks").empty();
setNavColor('bg-secondary');
enableStatusTimer=false;
$("#tasks_sect").css('visibility','collapse');
Promise.resolve(cmdname).delay(duration).then(function(cmdname) {
if(cmdname?.length >0){
showCmdMessage(cmdname,'MESSAGING_WARNING','Rebooting the ESP32.\n',true);
}
else {
showLocalMessage('MESSAGING_WARNING','Rebooting the ESP32.\n')
showLocalMessage('Rebooting the ESP32.\n','MESSAGING_WARNING')
}
console.log('now triggering reboot');
$.ajax({
@@ -299,6 +312,7 @@ function delay_reboot(duration,cmdname, ota=false){
error: handleExceptionResponse,
complete: function(response) {
console.log('reboot call completed');
enableStatusTimer=true;
Promise.resolve(cmdname).delay(6000).then(function(cmdname) {
if(cmdname?.length >0) HideCmdMessage(cmdname);
getCommands();
@@ -547,6 +561,9 @@ $(document).ready(function() {
});
$("#fwUpload").on("click", function() {
var upload_path = "/flash.json";
if(!recovery) $('#flash-status').text('Rebooting to OTA');
var fileInput = document.getElementById("flashfilename").files;
if (fileInput.length == 0) {
alert("No file selected!");
@@ -601,6 +618,7 @@ $(document).ready(function() {
$('#fwcheck').on("click", function() {
$("#releaseTable").html("");
$("#fwbranch").empty();
$.getJSON(releaseURL, function(data) {
var i = 0;
var branches = [];
@@ -918,9 +936,7 @@ function handleRecoveryMode(data){
$("#otadiv").show();
$('#uploaddiv').show();
$("footer.footer").removeClass('sl');
$("footer.footer").addClass('bg-warning');
$("#mainnav").addClass('bg-warning');
$('[name=secnav]').addClass('bg-warning');
setNavColor('bg-warning');
$("#boot-button").html('Reboot');
$("#boot-form").attr('action', '/reboot_ota.json');
} else {
@@ -929,9 +945,7 @@ function handleRecoveryMode(data){
$("#reboot_nav").show();
$("#otadiv").hide();
$('#uploaddiv').hide();
$("footer.footer").removeClass('bg-warning');
$('#mainnav').removeClass('bg-warning');
$('[name=secnav]').removeClass('bg-warning');
setNavColor('');
$("footer.footer").addClass('sl');
$("#boot-button").html('Recovery');
$("#boot-form").attr('action', '/recovery.json');

View File

@@ -1 +1 @@
{"project_name":"recovery","version":"custom.build","recovery":1,"Jack":"1","Voltage":0,"disconnect_count":0,"avg_conn_time":0,"is_i2c_locked":false,"urc":0,"ssid":"Abyssin","ip":"192.168.10.225","netmask":"255.255.255.0","gw":"192.168.10.1"}
{"project_name":"recovery","version":"custom.build","recovery":1,"Jack":"1","Voltage":0,"disconnect_count":0,"avg_conn_time":0,"is_i2c_locked":false,"urc":0,"ssid":"MyTestSSID","ip":"192.168.10.225","netmask":"255.255.255.0","gw":"192.168.10.1"}