Selaa lähdekoodia

supporting command line driven display configuration

Sebastien 5 vuotta sitten
vanhempi
commit
89765d9679

+ 155 - 0
components/cmd_i2c/cmd_i2ctools.c

@@ -12,6 +12,9 @@
 #include "driver/i2c.h"
 #include "esp_console.h"
 #include "esp_log.h"
+#include "string.h"
+#include "stdio.h"
+#include "config.h"
 
 #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
 #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
@@ -70,6 +73,147 @@ static struct {
     struct arg_end *end;
 } i2cconfig_args;
 
+static struct {
+	struct arg_lit *clear;
+	struct arg_int *address;
+	struct arg_int *sda;
+	struct arg_int *scl;
+	struct arg_int *width;
+	struct arg_int *height;
+	struct arg_str *name;
+	struct arg_str *driver;
+	struct arg_end *end;
+} i2cdisp_args;
+
+static struct {
+	struct arg_end *end;
+} i2cdisp_show_args;
+static int do_i2c_show_display(int argc, char **argv){
+	char * config_string = (char * )config_alloc_get(NVS_TYPE_STR, "display_config") ;
+	if(config_string){
+		ESP_LOGI(TAG,"Display configuration string is : \n"
+					"display_config = \"%s\"",config_string);
+		free(config_string);
+	}
+	else {
+		ESP_LOGW(TAG,"No display configuration found in nvs config display_config");
+	}
+	return 0;
+}
+
+static int do_i2c_set_display(int argc, char **argv)
+{
+	int sda = 0, scl=0, width=0, height=0, address=120;
+	char * name = strdup("I2S");
+	char * driver= strdup("SSD136");
+	char config_string[200]={};
+    int nerrors = arg_parse(argc, argv, (void **)&i2cdisp_args);
+    if (nerrors != 0) {
+        arg_print_errors(stderr, i2cdisp_args.end, argv[0]);
+        return 0;
+    }
+
+
+    /* Check "--clear" option */
+    if (i2cdisp_args.clear->count) {
+    	ESP_LOGW(TAG,"Clearing display config");
+    	config_set_value(NVS_TYPE_STR, "display_config", "");
+    }
+    /* Check "--address" option */
+    if (i2cdisp_args.address->count) {
+    	address=i2cdisp_args.address->ival[0];
+    }
+    /* Check "--sda" option */
+    if (i2cdisp_args.sda->count) {
+    	sda=i2cdisp_args.sda->ival[0];
+    }
+    else {
+    	ESP_LOGE(TAG,"Missing parameter: --sda");
+    	nerrors ++;
+    }
+	/* Check "--scl" option */
+	if (i2cdisp_args.scl->count) {
+		scl=i2cdisp_args.scl->ival[0];
+	}
+    else {
+    	ESP_LOGE(TAG,"Missing parameter: --scl");
+    	nerrors ++;
+    }
+
+	/* Check "--width" option */
+	if (i2cdisp_args.width->count) {
+		width=i2cdisp_args.width->ival[0];
+	}
+    else {
+    	ESP_LOGE(TAG,"Missing parameter: --width");
+    	nerrors ++;
+    }
+
+	/* Check "--height" option */
+	if (i2cdisp_args.height->count) {
+		height=i2cdisp_args.height->ival[0];
+	}
+    else {
+    	ESP_LOGE(TAG,"Missing parameter: --height");
+    	nerrors ++;
+    }
+	/* Check "--name" option */
+	if (i2cdisp_args.name->count) {
+		free(name);
+		name=strdup(i2cdisp_args.name->sval[0]);
+	}
+
+	/* Check "--name" option */
+	if (i2cdisp_args.driver->count) {
+		free(driver);
+		driver=strdup(i2cdisp_args.driver->sval[0]);
+	}
+	snprintf(config_string, sizeof(config_string),"%s:scl=%i,sda=%i,width=%i,height=%i,address=%i,driver=%s",name,scl,sda,width,height,address,driver );
+	free(name);
+	free(driver);
+
+	if(nerrors!=0){
+		return 0;
+	}
+
+	ESP_LOGI(TAG,"Updating display configuration string configuration to :\n"
+			"display_config = \"%s\"",config_string );
+
+
+	return config_set_value(NVS_TYPE_STR, "display_config", config_string)!=ESP_OK;
+}
+
+static void register_i2c_set_display(){
+	i2cdisp_args.address = arg_int0(NULL, "address", "<n>", "Set the I2C bus port number (decimal format, default 120)");
+	i2cdisp_args.sda = arg_int0("d", "sda", "<gpio>", "Set the gpio for I2C SDA");
+	i2cdisp_args.scl = arg_int0("c", "scl", "<gpio>", "Set the gpio for I2C SCL");
+	i2cdisp_args.width = arg_int0("w", "width", "<n>", "Set the display width");
+	i2cdisp_args.height = arg_int0("h", "height", "<n>", "Set the display height");
+	i2cdisp_args.name = arg_str0("n", "name", "<string>", "Set the display type. Default is I2S");
+	i2cdisp_args.driver = arg_str0("d", "driver", "<string>", "Set the display driver name");
+	i2cdisp_args.clear = arg_litn(NULL, "clear", 0, 1, "clear configuration");
+	i2cdisp_args.end = arg_end(2);
+	i2cdisp_show_args.end = arg_end(1);
+	const esp_console_cmd_t i2c_set_display= {
+	 		.command = "set_i2c_display",
+			.help="Sets the i2c display options for the board",
+			.hint = NULL,
+			.func = &do_i2c_set_display,
+			.argtable = &i2cdisp_args
+	};
+	const esp_console_cmd_t i2c_show_display= {
+			.command = "show_i2c_display",
+			.help="Sets the i2c display options for the board",
+			.hint = NULL,
+			.func = &do_i2c_show_display,
+			.argtable = &i2cdisp_show_args
+	};
+	ESP_ERROR_CHECK(esp_console_cmd_register(&i2c_set_display));
+	ESP_ERROR_CHECK(esp_console_cmd_register(&i2c_show_display));
+}
+
+
+
 static int do_i2cconfig_cmd(int argc, char **argv)
 {
     int nerrors = arg_parse(argc, argv, (void **)&i2cconfig_args);
@@ -112,6 +256,16 @@ static void register_i2cconfig(void)
     ESP_ERROR_CHECK(esp_console_cmd_register(&i2cconfig_cmd));
 }
 
+
+
+
+
+
+
+
+
+
+
 static int do_i2cdetect_cmd(int argc, char **argv)
 {
     i2c_master_driver_initialize();
@@ -407,4 +561,5 @@ void register_i2ctools(void)
     register_i2cget();
     register_i2cset();
     register_i2cdump();
+    register_i2c_set_display();
 }

+ 36 - 1
components/config/config.c

@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 #include "esp_system.h"
+#include "ctype.h"
 #include "esp_log.h"
 #include "esp_console.h"
 #include "esp_vfs_dev.h"
@@ -89,10 +90,10 @@ static void * free_fn(void * ptr){
 }
 #endif
 void init_cJSON(){
-	static cJSON_Hooks hooks;
 	// initialize cJSON hooks it uses SPIRAM memory
 	// as opposed to IRAM
 #ifndef RECOVERY_APPLICATION
+	static cJSON_Hooks hooks;
 	// In squeezelite mode, allocate memory from PSRAM.  Otherwise allocate from internal RAM
 	// as recovery will lock flash access when erasing FLASH or writing to OTA partition.
 	hooks.malloc_fn=&malloc_fn;
@@ -703,6 +704,39 @@ esp_err_t config_set_value(nvs_type_t nvs_type, const char *key, void * value){
 	return result;
 }
 
+#define IS_ALPHA(c) isalpha((int)c)
+#define TO_UPPER(c) toupper((int)c)
+
+
+
+
+char * strstri (const char * str1, const char * str2){
+	char *cp = (char *) str1;
+	char *s1, *s2;
+
+	if ( *str2=='\0' )
+		return((char *)str1);
+
+	while (*cp){
+			s1 = cp;
+			s2 = (char *) str2;
+			while ( *s1!='\0' && *s2!='\0' && (IS_ALPHA(*s1) && IS_ALPHA(*s2))?!(TO_UPPER(*s1) - TO_UPPER(*s2)):!(*s1-*s2)){
+				ESP_LOGW(TAG,"Matched [%c] = [%c] ", IS_ALPHA(*s1)?TO_UPPER(*s1):*s1,IS_ALPHA(*s2)?TO_UPPER(*s2):*s2);
+				++s1, ++s2;
+			}
+
+
+			if (*s2=='\0'){
+				ESP_LOGW(TAG,"String %s found!", str2);
+				return(cp);
+			}
+
+			++cp;
+			ESP_LOGW(TAG,"%s not found. s2 is [%c]. Moving forward to %s", str2, *s2, cp);
+	}
+	ESP_LOGW(TAG,"String %s not found", str2);
+	return(NULL);
+}
 IMPLEMENT_SET_DEFAULT(uint8_t,NVS_TYPE_U8);
 IMPLEMENT_SET_DEFAULT(int8_t,NVS_TYPE_I8);
 IMPLEMENT_SET_DEFAULT(uint16_t,NVS_TYPE_U16);
@@ -716,3 +750,4 @@ IMPLEMENT_GET_NUM(uint16_t,NVS_TYPE_U16);
 IMPLEMENT_GET_NUM(int16_t,NVS_TYPE_I16);
 IMPLEMENT_GET_NUM(uint32_t,NVS_TYPE_U32);
 IMPLEMENT_GET_NUM(int32_t,NVS_TYPE_I32);
+

+ 1 - 1
components/config/config.h

@@ -37,4 +37,4 @@ void * config_alloc_get(nvs_type_t nvs_type, const char *key) ;
 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);
-
+char * strstri (const char * str1, const char * str2);

+ 15 - 9
components/display/display.c

@@ -39,17 +39,23 @@ static bool display_handler(u8_t *data, int len);
 void display_init(void) {
 	char *item = config_alloc_get(NVS_TYPE_STR, "display_config");
 
-	if (item && *item) { 
-		handle = &SSD1306_handle;
-		if (handle->init(item)) {
-			slimp_handler_chain = slimp_handler;
-			slimp_handler = display_handler;
-			ESP_LOGI(TAG, "Display initialization successful");
-		} else {
-			ESP_LOGI(TAG, "Display initialization failed");
+	if (item && *item) {
+		char * drivername=strstr(item,"driver");
+		if( !drivername  || (drivername && (strstr(drivername,"SSD1306") || strstr(drivername,"ssd1306")))){
+			handle = &SSD1306_handle;
+			if (handle->init(item)) {
+				slimp_handler_chain = slimp_handler;
+				slimp_handler = display_handler;
+				ESP_LOGI(TAG, "Display initialization successful");
+			} else {
+				ESP_LOGE(TAG, "Display initialization failed");
+			}
+		}else {
+			ESP_LOGE(TAG,"Unknown display driver name in display config: %s",item);
+
 		}
 	} else {
-		ESP_LOGI(TAG, "no display");
+		ESP_LOGW(TAG, "no display");
 	}
 
 	if (item) free(item);

+ 24 - 9
components/display/driver_SSD1306.c

@@ -76,26 +76,41 @@ static bool display_init(char *config) {
 
 	if (strstr(config, "I2C")) {
 		int scl = -1, sda = -1;
-		int width = -1, height = -1;
+		int width = -1, height = -1, address=I2C_ADDRESS;
 		char *p;
-
+		ESP_LOGI(TAG, "Initializing I2C display with config: %s",config);
 		// no time for smart parsing - this is for tinkerers
 		if ((p = strcasestr(config, "scl")) != NULL) scl = atoi(strchr(p, '=') + 1);
 		if ((p = strcasestr(config, "sda")) != NULL) sda = atoi(strchr(p, '=') + 1);
 		if ((p = strcasestr(config, "width")) != NULL) width = atoi(strchr(p, '=') + 1);
 		if ((p = strcasestr(config, "height")) != NULL) height = atoi(strchr(p, '=') + 1);
+		if ((p = strcasestr(config, "address")) != NULL) address = atoi(strchr(p, '=') + 1);
 
 		if (sda != -1 && scl != -1 && width != -1 && height != -1) {
-			SSD1306_I2CMasterInitDefault( I2C_PORT, sda, scl );
-			SSD1306_I2CMasterAttachDisplayDefault( &I2CDisplay, width, height, I2C_ADDRESS, -1);
-			SSD1306_SetFont( &I2CDisplay, &Font_droid_sans_fallback_15x17 );
-			ESP_LOGI(TAG, "Initialized I2C display %dx%d (sda:%d, scl:%d)", width, height, sda, scl);
-			res = true;
+			res = SSD1306_I2CMasterInitDefault( I2C_PORT, sda, scl );
+			if(!res){
+				ESP_LOGE(TAG,"I2C Master Init failed");
+			}
+		}
+		if(res){
+			res = SSD1306_I2CMasterAttachDisplayDefault( &I2CDisplay, width, height, address, -1);
+			if(!res){
+				ESP_LOGE(TAG,"Attach Display default failed");
+			}
+		}
+		if(res){
+			res = SSD1306_SetFont( &I2CDisplay, &Font_droid_sans_fallback_15x17 );
+			if(!res){
+				ESP_LOGE(TAG,"Set Font failed");
+			}
+		}
+		if(res){
+			ESP_LOGI(TAG, "Initialized I2C display %dx%d (sda:%d, scl:%d, address:%02x)", width, height, sda, scl, address);
 		} else {
-			ESP_LOGI(TAG, "Cannot initialized I2C display %s [%dx%d sda:%d, scl:%d]", config, width, height, sda, scl);
+			ESP_LOGE(TAG, "Cannot initialized I2C display %s [%dx%d sda:%d, scl:%d, address:%02x]", config, width, height, sda, scl, address);
 		}
 	} else {
-		// other types
+		ESP_LOGE(TAG, "Non-I2C display not supported. Display config %s", config);
 	}
 
 	return res;

+ 10 - 3
components/services/audio_controls.c

@@ -18,7 +18,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
+#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -209,7 +209,7 @@ esp_err_t actrls_process_action (const cJSON * member, actrls_config_t *cur_conf
 
 
 esp_err_t actrls_process_member(const cJSON * member, actrls_config_t *cur_config) {
-	esp_err_t err = ESP_FAIL;
+	esp_err_t err = ESP_OK;
 	const actrls_config_map_t * h=actrls_config_map;
 
 	char * str = cJSON_Print(member);
@@ -219,6 +219,7 @@ esp_err_t actrls_process_member(const cJSON * member, actrls_config_t *cur_confi
 		ESP_LOGD(TAG,"found handler for member %s, json value %s", h->member,str?str:"");
 		err = h->handler(member, cur_config, h->offset);
 	} else {
+		err = ESP_FAIL;
 		ESP_LOGE(TAG, "Unknown json structure member : %s", str?str:"");
 	}
 
@@ -227,7 +228,7 @@ esp_err_t actrls_process_member(const cJSON * member, actrls_config_t *cur_confi
 }
 
 esp_err_t actrls_process_button(const cJSON * button, actrls_config_t *cur_config) {
-	esp_err_t err= ESP_FAIL;
+	esp_err_t err= ESP_OK;
 	const cJSON *member;
 
 	cJSON_ArrayForEach(member, button)
@@ -300,9 +301,15 @@ esp_err_t actrls_init_json(const char *config) {
 				esp_err_t loc_err = actrls_process_button(button, cur_config);
 				err = (err == ESP_OK) ? loc_err : err;
 				if (loc_err == ESP_OK) {
+
+					ESP_LOGI(TAG, "Calling button_create");
 					button_create((void*) cur_config, cur_config->gpio,cur_config->type, cur_config->pull,cur_config->debounce,
 									control_handler, cur_config->long_press, cur_config->shifter_gpio);
 				}
+				else{
+					ESP_LOGE(TAG,"Error parsing button structure.  Button will not be registered.");
+				}
+
 				cur_config++;
 			}
 		}