浏览代码

more refactoring

- jack & led moved to services
- output_i2s subscribes to jack detection
- add user-defined debounce timer to buttons
philippe44 5 年之前
父节点
当前提交
daef63fdea

+ 1 - 1
components/services/audio_controls.c

@@ -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((void*) (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, config[i].debounce, control_handler, config[i].long_press, config[i].shifter_gpio);
 	}
 }
 

+ 1 - 0
components/services/audio_controls.h

@@ -32,6 +32,7 @@ typedef struct {
 	int gpio;
 	int type;
 	bool pull;
+	int	debounce;
 	int long_press;
 	int shifter_gpio;
 	actrls_action_e normal[2], longpress[2], shifted[2], longshifted[2];	// [0] keypressed, [1] keyreleased

+ 5 - 4
components/services/buttons.c

@@ -43,6 +43,7 @@ static int n_buttons = 0;
 static EXT_RAM_ATTR struct button_s {
 	void *id;
 	int gpio, index;
+	int debounce;
 	button_handler handler;
 	struct button_s *shifter;
 	int	long_press;
@@ -63,7 +64,7 @@ static void IRAM_ATTR gpio_isr_handler(void* arg)
 	struct button_s *button = (struct button_s*) arg;
 	BaseType_t woken = pdFALSE;
 
-	if (xTimerGetPeriod(button->timer) > DEBOUNCE / portTICK_RATE_MS) xTimerChangePeriodFromISR(button->timer, DEBOUNCE / portTICK_RATE_MS, &woken); // does that restart the timer? 
+	if (xTimerGetPeriod(button->timer) > button->debounce / portTICK_RATE_MS) xTimerChangePeriodFromISR(button->timer, button->debounce / portTICK_RATE_MS, &woken); // does that restart the timer? 
 	else xTimerResetFromISR(button->timer, &woken);
 	// ESP_EARLY_LOGI(TAG, "INT gpio %u level %u", button->gpio, button->level);
 }
@@ -149,7 +150,7 @@ void dummy_handler(void *id, button_event_e event, button_press_e press) {
 /****************************************************************************************
  * Create buttons 
  */
-void button_create(void *id, int gpio, int type, bool pull, button_handler handler, int long_press, int shifter_gpio) { 
+void button_create(void *id, int gpio, int type, bool pull, int debounce, button_handler handler, int long_press, int shifter_gpio) { 
 	static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
 	static EXT_RAM_ATTR StackType_t xStack[BUTTON_STACK_SIZE] __attribute__ ((aligned (4)));
 
@@ -159,7 +160,6 @@ void button_create(void *id, int gpio, int type, bool pull, button_handler handl
 
 	if (!n_buttons) {
 		button_evt_queue = xQueueCreate(10, sizeof(struct button_s));
-		gpio_install_isr_service(0);
 		xTaskCreateStatic( (TaskFunction_t) buttons_task, "buttons_thread", BUTTON_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
 	}
 	
@@ -169,11 +169,12 @@ void button_create(void *id, int gpio, int type, bool pull, button_handler handl
 	// set mandatory parameters
 	buttons[n_buttons].id = id;
  	buttons[n_buttons].gpio = gpio;
+ 	buttons[n_buttons].debounce = debounce ? debounce: DEBOUNCE;
 	buttons[n_buttons].handler = handler;
 	buttons[n_buttons].long_press = long_press;
 	buttons[n_buttons].level = -1;
 	buttons[n_buttons].type = type;
-	buttons[n_buttons].timer = xTimerCreate("buttonTimer", DEBOUNCE / portTICK_RATE_MS, pdFALSE, (void *) &buttons[n_buttons], buttons_timer);
+	buttons[n_buttons].timer = xTimerCreate("buttonTimer", buttons[n_buttons].debounce / portTICK_RATE_MS, pdFALSE, (void *) &buttons[n_buttons], buttons_timer);
 	// little trick to find ourselves from queued copy
 	buttons[n_buttons].index = n_buttons;
 

+ 2 - 1
components/services/buttons.h

@@ -27,9 +27,10 @@ typedef enum { BUTTON_NORMAL, BUTTON_SHIFTED } button_press_e;
 typedef void (*button_handler)(void *id, button_event_e event, button_press_e mode, bool long_press);
 
 /* 
+set debounce to 0 for default (50ms)
 set long_press to 0 for no long-press
 set shifter_gpio to -1 for no shift
 NOTE: shifter buttons *must* be created before shiftee
 */
 
-void button_create(void *id, int gpio, int type, bool pull, button_handler handler, int long_press, int shifter_gpio);
+void button_create(void *id, int gpio, int type, bool pull, int debounce, button_handler handler, int long_press, int shifter_gpio);

+ 32 - 0
components/services/monitor.c

@@ -15,12 +15,17 @@
 #include "esp_system.h"
 #include "esp_log.h"
 #include "monitor.h"
+#include "driver/gpio.h"
+#include "buttons.h"
 
+#define JACK_GPIO	34
 #define MONITOR_TIMER	(10*1000)
 
 static const char TAG[] = "monitor";
 
 static TimerHandle_t monitor_timer;
+void (*jack_handler_svc)(bool inserted);
+bool jack_inserted_svc(void);
 
 /****************************************************************************************
  * 
@@ -33,12 +38,39 @@ static void monitor_callback(TimerHandle_t xTimer) {
 			heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM));
 }
 
+/****************************************************************************************
+ * 
+ */
+static void jack_handler_default(void *id, button_event_e event, button_press_e mode, bool long_press) {
+	ESP_LOGD(TAG, "Jack %s", event == BUTTON_PRESSED ? "inserted" : "removed");
+	if (jack_handler_svc) (*jack_handler_svc)(event == BUTTON_PRESSED);
+}
+
+/****************************************************************************************
+ * 
+ */
+bool jack_inserted_svc (void) {
+#ifdef JACK_GPIO
+	return !gpio_get_level(JACK_GPIO);
+#else
+	return false;
+#endif
+}
+
 /****************************************************************************************
  * 
  */
 void monitor_svc_init(void) {
 	ESP_LOGI(TAG, "Initializing monitoring");
 
+#ifdef JACK_GPIO
+	gpio_pad_select_gpio(JACK_GPIO);
+	gpio_set_direction(JACK_GPIO, GPIO_MODE_INPUT);
+
+	// re-use button management for jack handler, it's a GPIO after all
+	button_create(NULL, JACK_GPIO, BUTTON_LOW, false, 250, jack_handler_default, 0, -1);
+#endif
+
 	monitor_timer = xTimerCreate("monitor", MONITOR_TIMER / portTICK_RATE_MS, pdTRUE, NULL, monitor_callback);
 	xTimerStart(monitor_timer, portMAX_DELAY);
 }

+ 3 - 0
components/services/monitor.h

@@ -20,3 +20,6 @@
  
 #pragma once
 
+extern void (*jack_handler_svc)(bool inserted);
+extern bool jack_inserted_svc(void);
+

+ 16 - 1
components/services/services.c

@@ -7,6 +7,8 @@
 */
 
 #include <stdio.h>
+#include "esp_log.h"
+#include "driver/gpio.h"
 #include "battery.h"
 #include "led.h"
 #include "monitor.h"
@@ -17,11 +19,24 @@ extern void led_svc_init(void);
 
 static const char TAG[] = "services";
 
+#ifdef CONFIG_SQUEEZEAMP
+#define LED_GREEN_GPIO 	12
+#define LED_RED_GPIO	13
+#endif
+
 /****************************************************************************************
  * 
  */
 void services_init(void) {
+	gpio_install_isr_service(0);
+
+	ESP_LOGD(TAG,"Configuring LEDs");
+	led_svc_init();
+#ifdef CONFIG_SQUEEZEAMP
+	led_config(LED_GREEN, LED_GREEN_GPIO, 0);
+	led_config(LED_RED, LED_RED_GPIO, 0);
+#endif
+
 	battery_svc_init();
 	monitor_svc_init();
-	led_svc_init();
 }

+ 25 - 16
components/squeezelite/output_i2s.c

@@ -49,6 +49,7 @@ sure that using rate_delay would fix that
 #include <signal.h>
 #include "time.h"
 #include "led.h"
+#include "monitor.h"
 
 #define LOCK   mutex_lock(outputbuf->mutex)
 #define UNLOCK mutex_unlock(outputbuf->mutex)
@@ -121,7 +122,6 @@ static u8_t *obuf;
 static frames_t oframes;
 static bool spdif;
 static size_t dma_buf_frames;
-static int jack_status = -1;		// 0 = inserted
 
 DECLARE_ALL_MIN_MAX;
 
@@ -132,6 +132,7 @@ static void *output_thread_i2s_stats();
 static void dac_cmd(dac_cmd_e cmd, ...);
 static int tas57_detect(void);
 static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count);
+static void (*jack_handler_chain)(bool inserted);
 
 #ifdef CONFIG_SQUEEZEAMP
 
@@ -201,6 +202,19 @@ static u8_t tas57_addr;
 
 #endif
 
+/****************************************************************************************
+ * jack insertion handler
+ */
+static void jack_handler(bool inserted) {
+	// jack detection bounces a bit but that seems fine
+	if (jack_mutes_amp) {
+		LOG_INFO("switching amplifier %s", inserted ? "ON" : "OFF");
+		if (inserted) dac_cmd(DAC_ANALOGUE_OFF);
+		else dac_cmd(DAC_ANALOGUE_ON);
+	}
+	if (jack_handler_chain) (jack_handler_chain)(inserted);
+}
+
 /****************************************************************************************
  * Initialize the DAC output
  */
@@ -209,9 +223,7 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
 	
 #ifdef TAS57xx
 	LOG_INFO("Initializing TAS57xx ");
-	gpio_pad_select_gpio(JACK_GPIO);
-	gpio_set_direction(JACK_GPIO, GPIO_MODE_INPUT);
-			
+				
 	adc1_config_width(ADC_WIDTH_BIT_12);
     adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0);
     			
@@ -335,6 +347,12 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
 	
 	dac_cmd(DAC_STANDBY);
 
+	jack_handler_chain = jack_handler_svc;
+	jack_handler_svc = jack_handler;
+	
+	if (jack_mutes_amp && jack_inserted_svc()) dac_cmd(DAC_ANALOGUE_OFF);
+	else dac_cmd(DAC_ANALOGUE_ON);
+	
 	esp_pthread_cfg_t cfg = esp_pthread_get_default_config();
 	
     cfg.thread_name= "output_i2s";
@@ -451,19 +469,10 @@ static void *output_thread_i2s() {
 	while (running) {
 			
 		TIME_MEASUREMENT_START(timer_start);
-#ifdef TAS57xx
-		// handle jack insertion as a polling function (to avoid to have to do de-bouncing)
-		if (gpio_get_level(JACK_GPIO) != jack_status) {
-			jack_status = gpio_get_level(JACK_GPIO);
-			if (jack_mutes_amp) {
-				dac_cmd(jack_status ? DAC_ANALOGUE_ON : DAC_ANALOGUE_OFF);
-				LOG_INFO("Changing jack status %d", jack_status);
-			}	
-		}
-#endif
+
 		LOCK;
 		
-		// manage led display
+		// manage led display & analogue
 		if (state != output.state) {
 			LOG_INFO("Output state is %d", output.state);
 			if (output.state == OUTPUT_OFF) led_blink(LED_GREEN, 100, 2500);
@@ -474,7 +483,7 @@ static void *output_thread_i2s() {
 				led_blink(LED_GREEN, 200, 1000);
 			} else if (output.state == OUTPUT_RUNNING) {
 #ifdef TAS57xx				
-				if (!jack_mutes_amp || (jack_mutes_amp && jack_status)) dac_cmd(DAC_ANALOGUE_ON);
+				if (!jack_mutes_amp || !jack_inserted_svc()) dac_cmd(DAC_ANALOGUE_ON);
 #endif				
 				led_on(LED_GREEN);
 			}	

+ 3 - 7
components/wifi-manager/wifi_manager.c

@@ -62,6 +62,7 @@ Contains the freeRTOS task and all necessary support
 #include "cJSON.h"
 #include "nvs_utilities.h"
 #include "cmd_system.h"
+#include "monitor.h"
 
 #ifndef RECOVERY_APPLICATION
 #define RECOVERY_APPLICATION 0
@@ -70,12 +71,7 @@ Contains the freeRTOS task and all necessary support
 #ifndef SQUEEZELITE_ESP32_RELEASE_URL
 #define SQUEEZELITE_ESP32_RELEASE_URL "https://github.com/sle118/squeezelite-esp32/releases"
 #endif
-#ifdef CONFIG_SQUEEZEAMP
-#define JACK_GPIO	34
-#define JACK_LEVEL !gpio_get_level(JACK_GPIO)?"1":"0"
-#else
-#define JACK_LEVEL "N/A"
-#endif
+
 #define STR_OR_BLANK(p) p==NULL?"":p
 #define FREE_AND_NULL(p) if(p!=NULL){ free(p); p=NULL;}
 /* objects used to manipulate the main queue of events */
@@ -455,7 +451,7 @@ cJSON * wifi_manager_get_basic_info(cJSON **old){
 	cJSON_AddNumberToObject(root,"recovery",	RECOVERY_APPLICATION	);
 	cJSON_AddItemToObject(root, "ota_dsc", cJSON_CreateString(ota_get_status()));
 	cJSON_AddNumberToObject(root,"ota_pct",	ota_get_pct_complete()	);
-	cJSON_AddItemToObject(root, "Jack", cJSON_CreateString(JACK_LEVEL));
+	cJSON_AddItemToObject(root, "Jack", cJSON_CreateString(jack_inserted_svc() ? "1" : "0"));
 	cJSON_AddNumberToObject(root,"Voltage",	adc1_get_raw(ADC1_CHANNEL_7) / 4095. * (10+174)/10. * 1.1);
 	cJSON_AddNumberToObject(root,"disconnect_count", num_disconnect	);
 	cJSON_AddNumberToObject(root,"avg_conn_time", num_disconnect>0?(total_connected_time/num_disconnect):0	);

+ 8 - 20
main/esp_app_main.c

@@ -65,13 +65,6 @@ static const char TAG[] = "esp_app_main";
 #define DEFAULT_HOST_NAME "squeezelite"
 char * fwurl = NULL;
 
-#ifdef CONFIG_SQUEEZEAMP
-#define LED_GREEN_GPIO 	12
-#define LED_RED_GPIO	13
-#else
-#define LED_GREEN_GPIO 	-1
-#define LED_RED_GPIO	-1
-#endif
 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");
@@ -80,15 +73,15 @@ 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} },
-	{ 5, BUTTON_LOW, true, 1000, 4,  {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, {ACTRLS_TOGGLE, ACTRLS_NONE}, {BCTRLS_DOWN, ACTRLS_NONE} },
+	{ 4, BUTTON_LOW, true, 0, 1000, -1, {ACTRLS_VOLUP, ACTRLS_NONE}, 	{ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
+	{ 5, BUTTON_LOW, true, 0, 1000, 4,  {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, {ACTRLS_TOGGLE, ACTRLS_NONE}, {BCTRLS_DOWN, ACTRLS_NONE} },
 };
 
 static const actrls_config_t board_2[] = {
 	//								normal 							long						shifted						long shifted											
-	{ 21, BUTTON_LOW, true, 1000, -1, 	{ACTRLS_TOGGLE, ACTRLS_NONE}, {ACTRLS_STOP, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
-	{ 18, BUTTON_LOW, true, 1000, 21, {ACTRLS_VOLUP, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, 	{ACTRLS_FWD, ACTRLS_PLAY} },
-	{ 19, BUTTON_LOW, true, 1000, 21, {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_REW, ACTRLS_PLAY} },
+	{ 21, BUTTON_LOW, true, 0, 1000, -1, 	{ACTRLS_TOGGLE, ACTRLS_NONE}, {ACTRLS_STOP, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
+	{ 18, BUTTON_LOW, true, 0, 1000, 21, {ACTRLS_VOLUP, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, 	{ACTRLS_FWD, ACTRLS_PLAY} },
+	{ 19, BUTTON_LOW, true, 0, 1000, 21, {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_REW, ACTRLS_PLAY} },
 };
 
 static const struct {
@@ -372,6 +365,9 @@ void app_main()
 	ESP_LOGI(TAG,"Setting up config subsystem.");
 	config_init();
 
+	ESP_LOGD(TAG,"Configuring services");
+	services_init();
+
 	ESP_LOGI(TAG,"Registering default values");
 	register_default_nvs();
 
@@ -383,7 +379,6 @@ void app_main()
 	ESP_LOGD(TAG,"Getting firmware OTA URL (if any)");
 	fwurl = process_ota_url();
 
-
 	ESP_LOGD(TAG,"Getting value for WM bypass, nvs 'bypass_wm'");
 	char * bypass_wm = config_alloc_get_default(NVS_TYPE_STR, "bypass_wm", "0", 0);
 	if(bypass_wm==NULL)
@@ -395,13 +390,6 @@ 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", NULL, 0);
 	if (board_index) {
 		ESP_LOGD(TAG,"Initializing audio control buttons index %u", atoi(board_index));