Переглянути джерело

refactor services, increase max sockets - release

philippe44 5 роки тому
батько
коміт
26ecdf60d9
35 змінених файлів з 204 додано та 57 видалено
  1. 1 0
      build-scripts/16M-sdkconfig.defaults
  2. 1 1
      build-scripts/I2S-16MFlash-sdkconfig.defaults
  3. 1 1
      build-scripts/I2S-4MFlash-sdkconfig.defaults
  4. 1 0
      build-scripts/NonOTA-16M-sdkconfig.defaults
  5. 1 1
      build-scripts/NonOTA-I2S-16MFlash-sdkconfig.defaults
  6. 1 1
      build-scripts/NonOTA-I2S-4MFlash-sdkconfig.defaults
  7. 1 1
      build-scripts/NonOTA-SqueezeAmp-sdkconfig.defaults
  8. 1 1
      build-scripts/SqueezeAmp4MBFlash-sdkconfig.defaults
  9. 1 1
      build-scripts/SqueezeAmp8MBFlash-sdkconfig.defaults
  10. 1 0
      build-scripts/squeezelite-esp32-16M-sdkconfig.defaults
  11. 1 1
      build-scripts/squeezelite-esp32-I2S-16MFlash-sdkconfig.defaults
  12. 1 1
      build-scripts/squeezelite-esp32-I2S-4MFlash-NOAirplay-sdkconfig.defaults
  13. 1 1
      build-scripts/squeezelite-esp32-I2S-4MFlash-sdkconfig.defaults
  14. 1 1
      build-scripts/squeezelite-esp32-SqueezeAmp-sdkconfig.defaults
  15. 0 10
      components/io/component.mk
  16. 1 1
      components/raop/raop_sink.c
  17. 0 0
      components/services/CMakeLists.txt
  18. 2 2
      components/services/audio_controls.c
  19. 0 0
      components/services/audio_controls.h
  20. 57 0
      components/services/battery.c
  21. 10 0
      components/services/battery.h
  22. 1 1
      components/services/buttons.c
  23. 0 0
      components/services/buttons.h
  24. 0 0
      components/services/component.mk
  25. 4 0
      components/services/led.c
  26. 0 0
      components/services/led.h
  27. 44 0
      components/services/monitor.c
  28. 22 0
      components/services/monitor.h
  29. 27 0
      components/services/services.c
  30. 1 1
      components/squeezelite/component.mk
  31. 2 2
      components/squeezelite/controls.c
  32. 8 0
      components/squeezelite/controls.h
  33. 0 24
      components/squeezelite/output_i2s.c
  34. 1 1
      components/wifi-manager/wifi_manager.c
  35. 10 4
      main/esp_app_main.c

+ 1 - 0
build-scripts/16M-sdkconfig.defaults

@@ -121,6 +121,7 @@ CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
 CONFIG_ESP32_PHY_MAX_TX_POWER=20
 CONFIG_FREERTOS_HZ=100
 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_MAX_SOCKETS=16
 CONFIG_LWIP_NETIF_LOOPBACK=y
 CONFIG_LWIP_TCP_MSL=60000
 CONFIG_LWIP_TCP_SND_BUF_DEFAULT=8192

+ 1 - 1
build-scripts/I2S-16MFlash-sdkconfig.defaults

@@ -614,7 +614,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/I2S-4MFlash-sdkconfig.defaults

@@ -613,7 +613,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 0
build-scripts/NonOTA-16M-sdkconfig.defaults

@@ -117,6 +117,7 @@ CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
 CONFIG_ESP32_PHY_MAX_TX_POWER=20
 CONFIG_FREERTOS_HZ=100
 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_MAX_SOCKETS=16
 CONFIG_LWIP_NETIF_LOOPBACK=y
 CONFIG_LWIP_TCP_MSL=60000
 CONFIG_LWIP_TCP_SND_BUF_DEFAULT=8192

+ 1 - 1
build-scripts/NonOTA-I2S-16MFlash-sdkconfig.defaults

@@ -614,7 +614,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/NonOTA-I2S-4MFlash-sdkconfig.defaults

@@ -613,7 +613,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/NonOTA-SqueezeAmp-sdkconfig.defaults

@@ -602,7 +602,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/SqueezeAmp4MBFlash-sdkconfig.defaults

@@ -602,7 +602,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/SqueezeAmp8MBFlash-sdkconfig.defaults

@@ -295,7 +295,7 @@ CONFIG_LOG_DEFAULT_LEVEL=3
 CONFIG_LOG_COLORS=y
 CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y
 CONFIG_LWIP_ESP_GRATUITOUS_ARP=y

+ 1 - 0
build-scripts/squeezelite-esp32-16M-sdkconfig.defaults

@@ -115,6 +115,7 @@ CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
 CONFIG_ESP32_PHY_MAX_TX_POWER=20
 CONFIG_FREERTOS_HZ=100
 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_MAX_SOCKETS=16
 CONFIG_LWIP_NETIF_LOOPBACK=y
 CONFIG_LWIP_TCP_MSL=60000
 CONFIG_LWIP_TCP_SND_BUF_DEFAULT=8192

+ 1 - 1
build-scripts/squeezelite-esp32-I2S-16MFlash-sdkconfig.defaults

@@ -613,7 +613,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/squeezelite-esp32-I2S-4MFlash-NOAirplay-sdkconfig.defaults

@@ -608,7 +608,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/squeezelite-esp32-I2S-4MFlash-sdkconfig.defaults

@@ -637,7 +637,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 1 - 1
build-scripts/squeezelite-esp32-SqueezeAmp-sdkconfig.defaults

@@ -601,7 +601,7 @@ CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
 
 
 CONFIG_LWIP_TIMERS_ONDEMAND=y
-CONFIG_LWIP_MAX_SOCKETS=10
+CONFIG_LWIP_MAX_SOCKETS=16
 
 CONFIG_LWIP_SO_REUSE=y
 CONFIG_LWIP_SO_REUSE_RXTOALL=y

+ 0 - 10
components/io/component.mk

@@ -1,10 +0,0 @@
-#
-# Component Makefile
-#
-# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default,
-# this will take the sources in the src/ directory, compile them and link them into
-# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
-# please read the SDK documents if you need to do this.
-#
-
-COMPONENT_ADD_INCLUDEDIRS := .

+ 1 - 1
components/raop/raop_sink.c

@@ -111,7 +111,7 @@ void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) {
     ESP_ERROR_CHECK( mdns_init() );
     ESP_ERROR_CHECK( mdns_hostname_set(hostname) );
         
-    char * sink_name_buffer= (char *)config_alloc_get(NVS_TYPE_STR,"AirPlay_name");
+    char * sink_name_buffer= (char *)config_alloc_get(NVS_TYPE_STR,"airplay_name");
     if(sink_name_buffer != NULL){
     	memset(sink_name, 0x00, sizeof(sink_name));
     	strncpy(sink_name,sink_name_buffer,sizeof(sink_name)-1 );

+ 0 - 0
components/io/CMakeLists.txt → components/services/CMakeLists.txt


+ 2 - 2
components/audio_controls/audio_controls.c → components/services/audio_controls.c

@@ -27,7 +27,7 @@
 #include "buttons.h"
 #include "audio_controls.h"
 
-static const char * TAG = "audio_controls";
+static const char * TAG = "audio controls";
 
 static actrls_t default_controls, current_controls;
 
@@ -88,7 +88,7 @@ void down(void *id, button_event_e event, button_press_e press, bool longpress)
  */
 void actrls_init(int n, const actrls_config_t *config) {
 	for (int i = 0; i < n; i++) {
-		button_create(config + i, config[i].gpio, config[i].type, config[i].pull, control_handler, config[i].long_press, config[i].shifter_gpio);
+		button_create((void*) (config + i), config[i].gpio, config[i].type, config[i].pull, control_handler, config[i].long_press, config[i].shifter_gpio);
 	}
 }
 

+ 0 - 0
components/audio_controls/audio_controls.h → components/services/audio_controls.h


+ 57 - 0
components/services/battery.c

@@ -0,0 +1,57 @@
+/*
+   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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/timers.h"
+#include "esp_system.h"
+#include "esp_log.h"
+#include "driver/adc.h"
+#include "battery.h"
+
+#define BATTERY_TIMER	(10*1000)
+
+static const char TAG[] = "battery";
+
+#ifdef CONFIG_SQUEEZEAMP
+static struct {
+	float sum, avg;
+	int count;
+	TimerHandle_t timer;
+} battery;
+#endif
+
+/****************************************************************************************
+ * 
+ */
+static void battery_callback(TimerHandle_t xTimer) {
+	battery.sum += adc1_get_raw(ADC1_CHANNEL_7) / 4095. * (10+174)/10. * 1.1;
+	if (++battery.count == 30) {
+		battery.avg = battery.sum / battery.count;
+		battery.sum = battery.count = 0;
+		ESP_LOGI(TAG, "Voltage %.2fV", battery.avg);
+	}	
+}
+
+/****************************************************************************************
+ * 
+ */
+void battery_svc_init(void) {
+#ifdef CONFIG_SQUEEZEAMP			
+	ESP_LOGI(TAG, "Initializing battery");
+
+	adc1_config_width(ADC_WIDTH_BIT_12);
+    adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0);
+
+	battery.timer = xTimerCreate("battery", BATTERY_TIMER / portTICK_RATE_MS, pdTRUE, NULL, battery_callback);
+	xTimerStart(battery.timer, portMAX_DELAY);
+#endif				
+}

+ 10 - 0
components/services/battery.h

@@ -0,0 +1,10 @@
+/*
+   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.
+*/
+
+#pragma once
+

+ 1 - 1
components/audio_controls/buttons.c → components/services/buttons.c

@@ -32,7 +32,7 @@
 #include "driver/gpio.h"
 #include "buttons.h"
 
-static const char * TAG = "audio_controls";
+static const char * TAG = "buttons";
 
 static int n_buttons = 0;
 

+ 0 - 0
components/audio_controls/buttons.h → components/services/buttons.h


+ 0 - 0
components/audio_controls/component.mk → components/services/component.mk


+ 4 - 0
components/io/led.c → components/services/led.c

@@ -33,6 +33,10 @@ static struct led_s {
 	TimerHandle_t timer;
 } leds[MAX_LED];
 
+void led_svc_init(void) {
+	ESP_LOGI(TAG, "Initializing led");
+}
+
 static void vCallbackFunction( TimerHandle_t xTimer ) {
 	struct led_s *led = (struct led_s*) pvTimerGetTimerID (xTimer);
 	

+ 0 - 0
components/io/led.h → components/services/led.h


+ 44 - 0
components/services/monitor.c

@@ -0,0 +1,44 @@
+/*
+   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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/timers.h"
+#include "esp_system.h"
+#include "esp_log.h"
+#include "monitor.h"
+
+#define MONITOR_TIMER	(10*1000)
+
+static const char TAG[] = "monitor";
+
+static TimerHandle_t monitor_timer;
+
+/****************************************************************************************
+ * 
+ */
+static void monitor_callback(TimerHandle_t xTimer) {
+	ESP_LOGI(TAG, "Heap internal:%zu (min:%zu) external:%zu (min:%zu)", 
+			heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
+			heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
+			heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
+			heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
+}
+
+/****************************************************************************************
+ * 
+ */
+void monitor_svc_init(void) {
+	ESP_LOGI(TAG, "Initializing monitoring");
+
+	monitor_timer = xTimerCreate("monitor", MONITOR_TIMER / portTICK_RATE_MS, pdTRUE, NULL, monitor_callback);
+	xTimerStart(monitor_timer, portMAX_DELAY);
+}

+ 22 - 0
components/services/monitor.h

@@ -0,0 +1,22 @@
+/* 
+ *  Squeezelite for esp32
+ *
+ *  (c) Philippe G. 2019, philippe_44@outlook.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+ 
+#pragma once
+

+ 27 - 0
components/services/services.c

@@ -0,0 +1,27 @@
+/*
+   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.
+*/
+
+#include <stdio.h>
+#include "battery.h"
+#include "led.h"
+#include "monitor.h"
+
+extern void battery_svc_init(void);
+extern void monitor_svc_init(void);
+extern void led_svc_init(void);
+
+static const char TAG[] = "services";
+
+/****************************************************************************************
+ * 
+ */
+void services_init(void) {
+	battery_svc_init();
+	monitor_svc_init();
+	led_svc_init();
+}

+ 1 - 1
components/squeezelite/component.mk

@@ -15,7 +15,7 @@ CFLAGS += -O3 -DLINKALL -DLOOPBACK -DNO_FAAD -DRESAMPLE16 -DEMBEDDED -DTREMOR_ON
 	-I$(COMPONENT_PATH)/../codecs/inc/opusfile	\
 	-I$(COMPONENT_PATH)/../driver_bt			\
 	-I$(COMPONENT_PATH)/../raop					\
-	-I$(COMPONENT_PATH)/../audio_controls
+	-I$(COMPONENT_PATH)/../services
 
 #	-I$(COMPONENT_PATH)/../codecs/inc/faad2
 

+ 2 - 2
components/squeezelite/controls.c

@@ -69,7 +69,7 @@ static void lms_next(void) {
 	cli_send_cmd("button fwd");
 }
 
-const static actrls_t controls = {
+const actrls_t LMS_controls = {
 	lms_volume_up, lms_volume_down,	// volume up, volume down
 	lms_toggle, lms_play,	// toggle, play
 	lms_pause, lms_stop,	// pause, stop
@@ -121,7 +121,7 @@ static void notify(in_addr_t ip, u16_t hport, u16_t cport) {
  */
 void cli_controls_init(void) {
 	get_mac(mac);
-	actrls_set_default(controls);
+	actrls_set_default(LMS_controls);
 	chained_notify = server_notify;
 	server_notify = notify;
 }

+ 8 - 0
components/squeezelite/controls.h

@@ -0,0 +1,8 @@
+#ifndef CONTROLS_H
+#define CONTROLS_H
+
+#include "audio_controls.h"
+
+const extern actrls_t LMS_controls[];
+
+#endif // CONTROLS_H

+ 0 - 24
components/squeezelite/output_i2s.c

@@ -162,11 +162,6 @@ static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *cou
 #define TAS575x 0x98
 #define TAS578x	0x90
 
-static struct {
-	float sum, avg;
-	u16_t count;
-} battery;
-
 struct tas57xx_cmd_s {
 	u8_t reg;
 	u8_t value;
@@ -583,18 +578,7 @@ static void *output_thread_i2s() {
  * Stats output thread
  */
 static void *output_thread_i2s_stats() {
-	int memory_count = 0;
-
 	while (running) {
-#ifdef TAS57xx		
-		battery.sum += adc1_get_raw(ADC1_CHANNEL_7) / 4095. * (10+174)/10. * 1.1;
-		if (++battery.count == (300 * 1000) / STATS_PERIOD_MS) {
-			battery.avg = battery.sum / battery.count;
-			battery.sum = battery.count = 0;
-			LOG_INFO("Voltage %.2fV", battery.avg);
-		}	
-#endif		
-
 		LOCK;
 		output_state state = output.state;
 		UNLOCK;
@@ -618,14 +602,6 @@ static void *output_thread_i2s_stats() {
 			LOG_INFO("              ----------+----------+-----------+-----------+");
 			RESET_ALL_MIN_MAX;
 		}
-		if (loglevel == lDEBUG || !memory_count--) {
-			LOG_INFO("Heap internal:%zu (min:%zu) external:%zu (min:%zu)", 
-						heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
-						heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL),
-						heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
-						heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
-			memory_count = (60*1000) / STATS_PERIOD_MS;
-		}
 		usleep(STATS_PERIOD_MS *1000);
 	}
 	return NULL;

+ 1 - 1
components/wifi-manager/wifi_manager.c

@@ -1093,7 +1093,7 @@ void wifi_manager( void * pvParameters ){
 	BaseType_t xStatus;
 	EventBits_t uxBits;
 	uint8_t	retries = 0;
-	esp_err_t err=ESP_OK;
+
 	/* start http server */
 	http_server_start();
 

+ 10 - 4
main/esp_app_main.c

@@ -76,6 +76,8 @@ static bool bWifiConnected=false;
 extern const uint8_t server_cert_pem_start[] asm("_binary_github_pem_start");
 extern const uint8_t server_cert_pem_end[] asm("_binary_github_pem_end");
 
+extern void services_init(void);
+
 static const actrls_config_t board_1[] = {
 	//								normal 							long						shifted						long shifted											
 	{ 4, BUTTON_LOW, true, 1000, -1, {ACTRLS_VOLUP, ACTRLS_NONE}, 	{ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
@@ -393,15 +395,19 @@ void app_main()
 		bypass_wifi_manager=(strcmp(bypass_wm,"1")==0 ||strcasecmp(bypass_wm,"y")==0);
 	}
 
+	services_init();
+
 	ESP_LOGD(TAG,"Configuring Green led");
 	led_config(LED_GREEN, LED_GREEN_GPIO, 0);
 	ESP_LOGD(TAG,"Configuring Red led");
 	led_config(LED_RED, LED_RED_GPIO, 0);
 
-	char *board_index = config_alloc_get_default(NVS_TYPE_STR, "board_index", "0", 0);
-	ESP_LOGD(TAG,"Initializing audio control buttons index %u", atoi(board_index));
-	actrls_init(board_configs[atoi(board_index)].n, (actrls_config_t*) board_configs[atoi(board_index)].config);
-	free(board_index);
+	char *board_index = config_alloc_get_default(NVS_TYPE_STR, "board_index", NULL, 0);
+	if (board_index) {
+		ESP_LOGD(TAG,"Initializing audio control buttons index %u", atoi(board_index));
+		actrls_init(board_configs[atoi(board_index)].n, (actrls_config_t*) board_configs[atoi(board_index)].config);
+		free(board_index);
+	}
 
 	/* start the wifi manager */
 	ESP_LOGD(TAG,"Blinking led");