mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 12:37:01 +03:00
add a quick LED helper / prepare SqueezeAMP menuconfig
This commit is contained in:
@@ -46,8 +46,10 @@ nvs_set autoexec2 str -v "squeezelite -o \"BT -n 'MySpeaker'\" -b 500:2000 -R -u
|
|||||||
#pragma GCC optimize ("O0")
|
#pragma GCC optimize ("O0")
|
||||||
#pragma GCC pop_options
|
#pragma GCC pop_options
|
||||||
- opus & opusfile
|
- opus & opusfile
|
||||||
|
- for opus, the ESP-provided library seems to work, but opusfile is still needed
|
||||||
- per mad & few others, edit configure and change $ac_link to add -c (faking link)
|
- per mad & few others, edit configure and change $ac_link to add -c (faking link)
|
||||||
- change ac_files to remove ''
|
- change ac_files to remove ''
|
||||||
|
- add DEPS_CFLAGS and DEPS_LIBS to avoid pkg-config to be required
|
||||||
- better use helixaac
|
- better use helixaac
|
||||||
- set IDF_PATH=/home/esp-idf
|
- set IDF_PATH=/home/esp-idf
|
||||||
- set ESPPORT=COM9
|
- set ESPPORT=COM9
|
||||||
|
|||||||
10
components/io/component.mk
Normal file
10
components/io/component.mk
Normal 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 := .
|
||||||
101
components/io/led.c
Normal file
101
components/io/led.c
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
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 struct led_s {
|
||||||
|
gpio_num_t gpio;
|
||||||
|
bool on;
|
||||||
|
int onstate;
|
||||||
|
int ontime, offtime;
|
||||||
|
int waiton, waitoff;
|
||||||
|
TimerHandle_t timer;
|
||||||
|
} leds[MAX_LED];
|
||||||
|
|
||||||
|
static void vCallbackFunction( TimerHandle_t xTimer ) {
|
||||||
|
struct led_s *led = (struct led_s*) pvTimerGetTimerID (xTimer);
|
||||||
|
|
||||||
|
if (!led->timer) return;
|
||||||
|
|
||||||
|
led->on = !led->on;
|
||||||
|
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 wait) {
|
||||||
|
if (!leds[idx].gpio) return false;
|
||||||
|
|
||||||
|
if (leds[idx].timer) {
|
||||||
|
// low priority timers will wait
|
||||||
|
if (wait && xTimerIsTimerActive(leds[idx].timer)) {
|
||||||
|
leds[idx].waiton = ontime;
|
||||||
|
leds[idx].waitoff = offtime;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
xTimerStop(leds[idx].timer, BLOCKTIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
leds[idx].ontime = ontime;
|
||||||
|
leds[idx].offtime = offtime;
|
||||||
|
|
||||||
|
if (ontime == 0) {
|
||||||
|
gpio_set_level(leds[idx].gpio, !leds[idx].onstate);
|
||||||
|
} else if (offtime == 0) {
|
||||||
|
gpio_set_level(leds[idx].gpio, leds[idx].onstate);
|
||||||
|
} else {
|
||||||
|
if (!leds[idx].timer) leds[idx].timer = xTimerCreate("ledTimer", ontime / portTICK_RATE_MS, pdFALSE, (void *)&leds[idx], vCallbackFunction);
|
||||||
|
leds[idx].on = true;
|
||||||
|
gpio_set_level(leds[idx].gpio, leds[idx].onstate);
|
||||||
|
if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool led_release(int idx) {
|
||||||
|
if (!leds[idx].gpio) return false;
|
||||||
|
|
||||||
|
if (leds[idx].waiton) {
|
||||||
|
led_blink_core(idx, leds[idx].waiton, leds[idx].waitoff, false);
|
||||||
|
leds[idx].waiton = 0;
|
||||||
|
} else {
|
||||||
|
gpio_set_level(leds[idx].gpio, !leds[idx].onstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool led_config(int idx, gpio_num_t gpio, int onstate) {
|
||||||
|
if (idx >= MAX_LED) return false;
|
||||||
|
leds[idx].gpio = gpio;
|
||||||
|
leds[idx].onstate = onstate;
|
||||||
|
|
||||||
|
gpio_pad_select_gpio(gpio);
|
||||||
|
gpio_set_direction(gpio, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_set_level(gpio, !onstate);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
37
components/io/led.h
Normal file
37
components/io/led.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#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_wait(idx, on, off) led_blink_core(idx, on, off, true)
|
||||||
|
|
||||||
|
bool led_blink_core(int idx, int ontime, int offtime, bool wait);
|
||||||
|
bool led_release(int idx);
|
||||||
|
bool led_config(int idx, gpio_num_t gpio, int onstate);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# "main" pseudo-component makefile.
|
# "main" pseudo-component makefile.
|
||||||
#
|
#
|
||||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||||
CFLAGS += -O3 -DLINKALL -DLOOPBACK -DTAS575x -DNO_FAAD -DRESAMPLE16 -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4 \
|
CFLAGS += -O3 -DLINKALL -DLOOPBACK -DNO_FAAD -DRESAMPLE16 -DEMBEDDED -DTREMOR_ONLY -DBYTES_PER_FRAME=4 \
|
||||||
-I$(COMPONENT_PATH)/../codecs/inc \
|
-I$(COMPONENT_PATH)/../codecs/inc \
|
||||||
-I$(COMPONENT_PATH)/../codecs/inc/mad \
|
-I$(COMPONENT_PATH)/../codecs/inc/mad \
|
||||||
-I$(COMPONENT_PATH)/../codecs/inc/alac \
|
-I$(COMPONENT_PATH)/../codecs/inc/alac \
|
||||||
|
|||||||
@@ -43,9 +43,11 @@ sure that using rate_delay would fix that
|
|||||||
#include "squeezelite.h"
|
#include "squeezelite.h"
|
||||||
#include "driver/i2s.h"
|
#include "driver/i2s.h"
|
||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
#include "perf_trace.h"
|
#include "perf_trace.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
#define LOCK mutex_lock(outputbuf->mutex)
|
#define LOCK mutex_lock(outputbuf->mutex)
|
||||||
#define UNLOCK mutex_unlock(outputbuf->mutex)
|
#define UNLOCK mutex_unlock(outputbuf->mutex)
|
||||||
@@ -109,7 +111,18 @@ static void *output_thread_i2s();
|
|||||||
static void *output_thread_i2s_stats();
|
static void *output_thread_i2s_stats();
|
||||||
static void dac_cmd(dac_cmd_e cmd, ...);
|
static void dac_cmd(dac_cmd_e cmd, ...);
|
||||||
|
|
||||||
#ifdef TAS575x
|
#ifdef CONFIG_SQUEEZEAMP
|
||||||
|
|
||||||
|
#define TAS575x
|
||||||
|
|
||||||
|
#undef CONFIG_I2S_BCK_IO
|
||||||
|
#define CONFIG_I2S_BCK_IO 33
|
||||||
|
#undef CONFIG_I2S_WS_IO
|
||||||
|
#define CONFIG_I2S_WS_IO 25
|
||||||
|
#undef CONFIG_I2S_DO_IO
|
||||||
|
#define CONFIG_I2S_DO_IO 32
|
||||||
|
#undef CONFIG_I2S_NUM
|
||||||
|
#define CONFIG_I2S_NUM 0
|
||||||
|
|
||||||
#define I2C_PORT 0
|
#define I2C_PORT 0
|
||||||
#define I2C_ADDR 0x4c
|
#define I2C_ADDR 0x4c
|
||||||
@@ -151,7 +164,13 @@ static const struct tas575x_cmd_s tas575x_cmd[] = {
|
|||||||
void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
|
void output_init_i2s(log_level level, char *device, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
|
||||||
loglevel = level;
|
loglevel = level;
|
||||||
|
|
||||||
#ifdef TAS575x
|
#ifdef TAS575x
|
||||||
|
gpio_pad_select_gpio(39);
|
||||||
|
gpio_set_direction(39, GPIO_MODE_INPUT);
|
||||||
|
|
||||||
|
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||||
|
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_0);
|
||||||
|
|
||||||
// init volume & mute
|
// init volume & mute
|
||||||
gpio_pad_select_gpio(VOLUME_GPIO);
|
gpio_pad_select_gpio(VOLUME_GPIO);
|
||||||
gpio_set_direction(VOLUME_GPIO, GPIO_MODE_OUTPUT);
|
gpio_set_direction(VOLUME_GPIO, GPIO_MODE_OUTPUT);
|
||||||
@@ -333,6 +352,9 @@ static void *output_thread_i2s() {
|
|||||||
int discard = 0;
|
int discard = 0;
|
||||||
uint32_t fullness = gettime_ms();
|
uint32_t fullness = gettime_ms();
|
||||||
bool synced;
|
bool synced;
|
||||||
|
#ifdef TAS575x
|
||||||
|
output_state state = OUTPUT_OFF;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
|
|
||||||
@@ -340,6 +362,16 @@ static void *output_thread_i2s() {
|
|||||||
|
|
||||||
LOCK;
|
LOCK;
|
||||||
|
|
||||||
|
#ifdef TAS575x
|
||||||
|
// manage led display
|
||||||
|
if (state != output.state) {
|
||||||
|
if (output.state == OUTPUT_OFF) led_blink(LED_GREEN, 100, 2500);
|
||||||
|
else if (output.state == OUTPUT_STOPPED) led_blink_wait(LED_GREEN, 200, 1000);
|
||||||
|
else if (output.state == OUTPUT_RUNNING) led_on(LED_GREEN);
|
||||||
|
}
|
||||||
|
state = output.state;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (output.state == OUTPUT_OFF) {
|
if (output.state == OUTPUT_OFF) {
|
||||||
UNLOCK;
|
UNLOCK;
|
||||||
LOG_INFO("Output state is off.");
|
LOG_INFO("Output state is off.");
|
||||||
@@ -348,6 +380,7 @@ static void *output_thread_i2s() {
|
|||||||
i2s_stop(CONFIG_I2S_NUM);
|
i2s_stop(CONFIG_I2S_NUM);
|
||||||
dac_cmd(DAC_OFF);
|
dac_cmd(DAC_OFF);
|
||||||
}
|
}
|
||||||
|
LOG_ERROR("Jack %d Voltage %.2fV", !gpio_get_level(39), adc1_get_raw(ADC1_CHANNEL_0) / 4095. * (10+169)/10. * 1.1);
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
continue;
|
continue;
|
||||||
} else if (output.state == OUTPUT_STOPPED) {
|
} else if (output.state == OUTPUT_STOPPED) {
|
||||||
@@ -389,7 +422,7 @@ static void *output_thread_i2s() {
|
|||||||
LOG_INFO("Restarting I2S.");
|
LOG_INFO("Restarting I2S.");
|
||||||
i2s_zero_dma_buffer(CONFIG_I2S_NUM);
|
i2s_zero_dma_buffer(CONFIG_I2S_NUM);
|
||||||
i2s_start(CONFIG_I2S_NUM);
|
i2s_start(CONFIG_I2S_NUM);
|
||||||
dac_cmd(DAC_ON);
|
dac_cmd(DAC_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this does not work well as set_sample_rates resets the fifos (and it's too early)
|
// this does not work well as set_sample_rates resets the fifos (and it's too early)
|
||||||
|
|||||||
@@ -123,26 +123,17 @@ menu "Squeezelite-ESP32"
|
|||||||
menu "Audio Output"
|
menu "Audio Output"
|
||||||
choice OUTPUT_TYPE
|
choice OUTPUT_TYPE
|
||||||
prompt "Output Type"
|
prompt "Output Type"
|
||||||
default DACAUDIO
|
default BASIC_I2C_BT
|
||||||
help
|
help
|
||||||
Type of output for squeezelite to send audio to
|
Type of hardware platform
|
||||||
config DACAUDIO
|
config SQUEEZEAMP
|
||||||
bool "DAC over I2S"
|
bool "SqueezeAMP (TAS575x & Bluetooth)"
|
||||||
config BTAUDIO
|
config BASIC_I2C_BT
|
||||||
bool "Bluetooth A2DP"
|
bool "Generic I2S & Bluetooth"
|
||||||
endchoice
|
endchoice
|
||||||
config OUTPUT_NAME
|
|
||||||
string
|
menu "DAC I2S settings"
|
||||||
default ""
|
depends on BASIC_I2C_BT
|
||||||
default "BT" if BTAUDIO
|
|
||||||
default "DAC" if DACAUDIO
|
|
||||||
|
|
||||||
config OUTPUT_RATES
|
|
||||||
string "Output rates"
|
|
||||||
default "44100"
|
|
||||||
help
|
|
||||||
<rates>[:<delay>] Sample rates supported, allows output to be off when squeezelite is started; rates = <maxrate>|<minrate>-<maxrate>|<rate1>,<rate2>,<rate3>; delay = optional delay switching rates in ms
|
|
||||||
menu "DAC I2S settings"
|
|
||||||
config I2S_NUM
|
config I2S_NUM
|
||||||
int "I2S channel (0 or 1). "
|
int "I2S channel (0 or 1). "
|
||||||
default 0
|
default 0
|
||||||
@@ -180,6 +171,7 @@ menu "Squeezelite-ESP32"
|
|||||||
default 24 if I2S_BITS_PER_CHANNEL_24
|
default 24 if I2S_BITS_PER_CHANNEL_24
|
||||||
default 8 if I2S_BITS_PER_CHANNEL_8
|
default 8 if I2S_BITS_PER_CHANNEL_8
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "A2DP settings"
|
menu "A2DP settings"
|
||||||
config A2DP_SINK_NAME
|
config A2DP_SINK_NAME
|
||||||
string "Name of Bluetooth A2DP device"
|
string "Name of Bluetooth A2DP device"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "tcpip_adapter.h"
|
#include "tcpip_adapter.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
#define JOIN_TIMEOUT_MS (10000)
|
#define JOIN_TIMEOUT_MS (10000)
|
||||||
|
|
||||||
@@ -46,8 +47,10 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
|||||||
{
|
{
|
||||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
|
led_blink(LED_GREEN, 250, 250);
|
||||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||||
|
led_release(LED_GREEN);
|
||||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,6 +92,7 @@ static void initialise_wifi(void)
|
|||||||
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
|
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
|
||||||
ESP_ERROR_CHECK( esp_wifi_start() );
|
ESP_ERROR_CHECK( esp_wifi_start() );
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
led_blink(LED_GREEN, 250, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wifi_join(const char *ssid, const char *pass, int timeout_ms)
|
static bool wifi_join(const char *ssid, const char *pass, int timeout_ms)
|
||||||
|
|||||||
@@ -18,10 +18,21 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "platform_esp32.h"
|
#include "platform_esp32.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_SQUEEZEAMP
|
||||||
|
#define LED_GREEN_GPIO 12
|
||||||
|
#define LED_RED_GPIO 13
|
||||||
|
#else
|
||||||
|
#define LED_GREEN_GPIO 0
|
||||||
|
#define LED_RED_GPIO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
void app_main()
|
void app_main()
|
||||||
{
|
{
|
||||||
|
led_config(LED_GREEN, LED_GREEN_GPIO, 0);
|
||||||
|
led_config(LED_RED, LED_RED_GPIO, 0);
|
||||||
|
|
||||||
console_start();
|
console_start();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user