more refactoring

- jack & led moved to services
- output_i2s subscribes to jack detection
- add user-defined debounce timer to buttons
This commit is contained in:
philippe44
2020-01-08 19:09:53 -08:00
parent 1409e1ccbe
commit daef63fdea
10 changed files with 96 additions and 50 deletions

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

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

View File

@@ -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();
}

View File

@@ -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,8 +223,6 @@ 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);
}

View File

@@ -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 );

View File

@@ -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));