refactor services, increase max sockets - release

This commit is contained in:
philippe44
2020-01-06 16:08:15 -08:00
parent d301a2d9df
commit 26ecdf60d9
35 changed files with 204 additions and 57 deletions

View File

@@ -0,0 +1,6 @@
idf_component_register(SRCS "led.c"
INCLUDE_DIRS . ../tools/
)

View File

@@ -0,0 +1,115 @@
/*
* audio control callbacks
*
* (c) Sebastien 2019
* 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/>.
*
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "esp_system.h"
#include "esp_log.h"
#include "buttons.h"
#include "audio_controls.h"
static const char * TAG = "audio controls";
static actrls_t default_controls, current_controls;
static void control_handler(void *id, button_event_e event, button_press_e press, bool long_press) {
actrls_config_t *key = (actrls_config_t*) id;
actrls_action_e action;
ESP_LOGD(TAG, "control gpio:%u press:%u long:%u event:%u", key->gpio, press, long_press, event);
switch(press) {
case BUTTON_NORMAL:
if (long_press) action = key->longpress[event == BUTTON_PRESSED ? 0 : 1];
else action = key->normal[event == BUTTON_PRESSED ? 0 : 1];
break;
case BUTTON_SHIFTED:
if (long_press) action = key->longshifted[event == BUTTON_PRESSED ? 0 : 1];
else action = key->shifted[event == BUTTON_PRESSED ? 0 : 1];
break;
default:
action = ACTRLS_NONE;
break;
}
if (action != ACTRLS_NONE) {
ESP_LOGD(TAG, " calling action %u", action);
if (current_controls[action]) (*current_controls[action])();
}
}
/*
void up(void *id, button_event_e event, button_press_e press, bool longpress) {
if (press == BUTTON_NORMAL) {
if (longpress) ESP_LOGI(TAG, "up long %u", event);
else ESP_LOGI(TAG, "up %u", event);
} else if (press == BUTTON_SHIFTED) {
if (longpress) ESP_LOGI(TAG, "up shifted long %u", event);
else ESP_LOGI(TAG, "up shifted %u", event);
} else {
ESP_LOGI(TAG, "don't know what we are doing here %u", event);
}
}
void down(void *id, button_event_e event, button_press_e press, bool longpress) {
if (press == BUTTON_NORMAL) {
if (longpress) ESP_LOGI(TAG, "down long %u", event);
else ESP_LOGI(TAG, "down %u", event);
} else if (press == BUTTON_SHIFTED) {
if (longpress) ESP_LOGI(TAG, "down shifted long %u", event);
else ESP_LOGI(TAG, "down shifted %u", event);
} else {
ESP_LOGI(TAG, "don't know what we are doing here %u", event);
}
}
*/
/****************************************************************************************
*
*/
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);
}
}
/****************************************************************************************
*
*/
void actrls_set_default(const actrls_t controls) {
memcpy(default_controls, controls, sizeof(actrls_t));
memcpy(current_controls, default_controls, sizeof(actrls_t));
}
/****************************************************************************************
*
*/
void actrls_set(const actrls_t controls) {
memcpy(current_controls, controls, sizeof(actrls_t));
}
/****************************************************************************************
*
*/
void actrls_unset(void) {
memcpy(current_controls, default_controls, sizeof(actrls_t));
}

View File

@@ -0,0 +1,42 @@
/*
* (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
#include "buttons.h"
// BEWARE: this is the index of the array of action below
typedef enum { ACTRLS_NONE = -1, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY,
ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT,
ACTRLS_MAX
} actrls_action_e;
typedef void (*actrls_handler)(void);
typedef actrls_handler actrls_t[ACTRLS_MAX - ACTRLS_NONE - 1];
typedef struct {
int gpio;
int type;
bool pull;
int long_press;
int shifter_gpio;
actrls_action_e normal[2], longpress[2], shifted[2], longshifted[2]; // [0] keypressed, [1] keyreleased
} actrls_config_t;
void actrls_init(int n, const actrls_config_t *config);
void actrls_set_default(const actrls_t controls);
void actrls_set(const actrls_t controls);
void actrls_unset(void);

View File

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

View File

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

View File

@@ -0,0 +1,204 @@
/*
* a crude button press/long-press/shift management based on GPIO
*
* (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/>.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_task.h"
#include "driver/gpio.h"
#include "buttons.h"
static const char * TAG = "buttons";
static int n_buttons = 0;
#define BUTTON_STACK_SIZE 4096
#define MAX_BUTTONS 16
#define DEBOUNCE 50
static EXT_RAM_ATTR struct button_s {
void *id;
int gpio, index;
button_handler handler;
struct button_s *shifter;
int long_press;
bool long_timer, shifted, shifting;
int type, level;
TimerHandle_t timer;
} buttons[MAX_BUTTONS];
static xQueueHandle button_evt_queue = NULL;
static void buttons_task(void* arg);
/****************************************************************************************
* GPIO low-level handler
*/
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?
else xTimerResetFromISR(button->timer, &woken);
// ESP_EARLY_LOGI(TAG, "INT gpio %u level %u", button->gpio, button->level);
}
/****************************************************************************************
* Buttons debounce/longpress timer
*/
static void buttons_timer( TimerHandle_t xTimer ) {
struct button_s *button = (struct button_s*) pvTimerGetTimerID (xTimer);
button->level = gpio_get_level(button->gpio);
if (button->shifter && button->shifter->type == button->shifter->level) button->shifter->shifting = true;
if (button->long_press && !button->long_timer && button->level == button->type) {
// detect a long press, so hold event generation
ESP_LOGD(TAG, "setting long timer gpio:%u level:%u", button->gpio, button->level);
xTimerChangePeriod(xTimer, button->long_press / portTICK_RATE_MS, 0);
button->long_timer = true;
} else {
// send a button pressed/released event (content is copied in queue)
ESP_LOGD(TAG, "sending event for gpio:%u level:%u", button->gpio, button->level);
// queue will have a copy of button's context
xQueueSend(button_evt_queue, button, 0);
button->long_timer = false;
}
}
/****************************************************************************************
* Tasks that calls the appropriate functions when buttons are pressed
*/
static void buttons_task(void* arg) {
ESP_LOGI(TAG, "starting button tasks");
while (1) {
struct button_s button;
button_event_e event;
button_press_e press;
if (!xQueueReceive(button_evt_queue, &button, portMAX_DELAY)) continue;
event = (button.level == button.type) ? BUTTON_PRESSED : BUTTON_RELEASED;
ESP_LOGD(TAG, "received event:%u from gpio:%u level:%u (timer %u shifting %u)", event, button.gpio, button.level, button.long_timer, button.shifting);
// find if shifting is activated
if (button.shifter && button.shifter->type == button.shifter->level) press = BUTTON_SHIFTED;
else press = BUTTON_NORMAL;
/*
long_timer will be set either because we truly have a long press
or we have a release before the long press timer elapsed, so two
events shall be sent
*/
if (button.long_timer) {
if (event == BUTTON_RELEASED) {
// early release of a long-press button, send press/release
if (!button.shifting) {
(*button.handler)(button.id, BUTTON_PRESSED, press, false);
(*button.handler)(button.id, BUTTON_RELEASED, press, false);
}
// button is a copy, so need to go to real context
buttons[button.index].shifting = false;
} else if (!button.shifting) {
// normal long press and not shifting so don't discard
(*button.handler)(button.id, BUTTON_PRESSED, press, true);
}
} else {
// normal press/release of a button or release of a long-press button
if (!button.shifting) (*button.handler)(button.id, event, press, button.long_press);
// button is a copy, so need to go to real context
buttons[button.index].shifting = false;
}
}
}
/****************************************************************************************
* dummy button handler
*/
void dummy_handler(void *id, button_event_e event, button_press_e press) {
ESP_LOGW(TAG, "should not be here");
}
/****************************************************************************************
* Create buttons
*/
void button_create(void *id, int gpio, int type, bool pull, 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)));
if (n_buttons >= MAX_BUTTONS) return;
ESP_LOGI(TAG, "creating button using GPIO %u, type %u, pull-up/down %u, long press %u shifter %u", gpio, type, pull, long_press, shifter_gpio);
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);
}
// just in case this structure is allocated in a future release
memset(buttons + n_buttons, 0, sizeof(struct button_s));
// set mandatory parameters
buttons[n_buttons].id = id;
buttons[n_buttons].gpio = gpio;
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);
// little trick to find ourselves from queued copy
buttons[n_buttons].index = n_buttons;
for (int i = 0; i < n_buttons; i++) {
if (buttons[i].gpio == shifter_gpio) {
buttons[n_buttons].shifter = buttons + i;
// a shifter must have a long-press handler
if (!buttons[i].long_press) buttons[i].long_press = -1;
break;
}
}
gpio_set_direction(gpio, GPIO_MODE_INPUT);
// we need any edge detection
gpio_set_intr_type(gpio, GPIO_INTR_ANYEDGE);
// do we need pullup or pulldown
if (pull) {
if (type == BUTTON_LOW) gpio_set_pull_mode(gpio, GPIO_PULLUP_ONLY);
else gpio_set_pull_mode(gpio, GPIO_PULLDOWN_ONLY);
}
gpio_isr_handler_add(gpio, gpio_isr_handler, (void*) &buttons[n_buttons]);
gpio_intr_enable(gpio);
n_buttons++;
}

View File

@@ -0,0 +1,35 @@
/*
* (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
// button type (pressed = LOW or HIGH)
#define BUTTON_LOW 0
#define BUTTON_HIGH 1
typedef enum { BUTTON_PRESSED, BUTTON_RELEASED } button_event_e;
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 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);

View File

@@ -0,0 +1,10 @@
#
# 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 := .

137
components/services/led.c Normal file
View File

@@ -0,0 +1,137 @@
/*
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/task.h"
#include "freertos/timers.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "led.h"
#define MAX_LED 8
#define BLOCKTIME 10 // up to portMAX_DELAY
static const char TAG[] = "led";
static struct led_s {
gpio_num_t gpio;
bool on;
int onstate;
int ontime, offtime;
int pushedon, pushedoff;
bool pushed;
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);
if (!led->timer) return;
led->on = !led->on;
ESP_LOGD(TAG,"led vCallbackFunction setting gpio %d level", led->gpio);
gpio_set_level(led->gpio, led->on ? led->onstate : !led->onstate);
// was just on for a while
if (!led->on && led->offtime == -1) return;
// regular blinking
xTimerChangePeriod(xTimer, (led->on ? led->ontime : led->offtime) / portTICK_RATE_MS, BLOCKTIME);
}
bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
if (!leds[idx].gpio || leds[idx].gpio<0 ) return false;
ESP_LOGD(TAG,"led_blink_core");
if (leds[idx].timer) {
// normal requests waits if a pop is pending
if (!pushed && leds[idx].pushed) {
leds[idx].pushedon = ontime;
leds[idx].pushedoff = offtime;
return true;
}
xTimerStop(leds[idx].timer, BLOCKTIME);
}
// save current state if not already pushed
if (!leds[idx].pushed) {
leds[idx].pushedon = leds[idx].ontime;
leds[idx].pushedoff = leds[idx].offtime;
leds[idx].pushed = pushed;
}
// then set new one
leds[idx].ontime = ontime;
leds[idx].offtime = offtime;
if (ontime == 0) {
ESP_LOGD(TAG,"led %d, setting reverse level", idx);
gpio_set_level(leds[idx].gpio, !leds[idx].onstate);
} else if (offtime == 0) {
ESP_LOGD(TAG,"led %d, setting level", idx);
gpio_set_level(leds[idx].gpio, leds[idx].onstate);
} else {
if (!leds[idx].timer) {
ESP_LOGD(TAG,"led %d, Creating timer", idx);
leds[idx].timer = xTimerCreate("ledTimer", ontime / portTICK_RATE_MS, pdFALSE, (void *)&leds[idx], vCallbackFunction);
}
leds[idx].on = true;
ESP_LOGD(TAG,"led %d, Setting gpio %d", idx, leds[idx].gpio);
gpio_set_level(leds[idx].gpio, leds[idx].onstate);
ESP_LOGD(TAG,"led %d, Starting timer.", idx);
if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false;
}
ESP_LOGD(TAG,"led %d, led_blink_core_done", idx);
return true;
}
bool led_unpush(int idx) {
if (!leds[idx].gpio || leds[idx].gpio<0) return false;
led_blink_core(idx, leds[idx].pushedon, leds[idx].pushedoff, true);
leds[idx].pushed = false;
return true;
}
bool led_config(int idx, gpio_num_t gpio, int onstate) {
if(gpio<0){
ESP_LOGW(TAG,"LED GPIO not configured");
return false;
}
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s", idx, gpio, onstate>0?"On":"Off");
if (idx >= MAX_LED) return false;
leds[idx].gpio = gpio;
leds[idx].onstate = onstate;
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s. Selecting GPIO pad", idx, gpio, onstate>0?"On":"Off");
gpio_pad_select_gpio(gpio);
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s. Setting direction to OUTPUT", idx, gpio, onstate>0?"On":"Off");
gpio_set_direction(gpio, GPIO_MODE_OUTPUT);
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s. Setting State to %d", idx, gpio, onstate>0?"On":"Off", onstate);
gpio_set_level(gpio, !onstate);
ESP_LOGD(TAG,"Done configuring the led");
return true;
}
bool led_unconfig(int idx) {
if (idx >= MAX_LED) return false;
if (leds[idx].timer) xTimerDelete(leds[idx].timer, BLOCKTIME);
leds[idx].timer = NULL;
return true;
}

38
components/services/led.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* Squeezelite for esp32
*
* (c) Sebastien 2019
* 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/>.
*
*/
#ifndef LED_H
#define LED_H
#include "driver/gpio.h"
enum { LED_GREEN = 0, LED_RED };
#define led_on(idx) led_blink_core(idx, 1, 0, false)
#define led_off(idx) led_blink_core(idx, 0, 0, false)
#define led_blink(idx, on, off) led_blink_core(idx, on, off, false)
#define led_blink_pushed(idx, on, off) led_blink_core(idx, on, off, true)
bool led_config(int idx, gpio_num_t gpio, int onstate);
bool led_unconfig(int idx);
bool led_blink_core(int idx, int ontime, int offtime, bool push);
bool led_unpush(int idx);
#endif

View File

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

View File

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

View File

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