mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-06 03:27:01 +03:00
headphone, bass/treble, battery from LMS
This commit is contained in:
1
TODO
1
TODO
@@ -2,3 +2,4 @@
|
||||
although they are almost static (expect output). This creates a risk of
|
||||
memory fragmentation, especially because the large output is re-allocated for
|
||||
AirPlay
|
||||
- libflac in lpc.c can be unrolled - that gains 43k of code, at the expense of 4% CPU
|
||||
@@ -33,8 +33,12 @@ static struct {
|
||||
int channel;
|
||||
float sum, avg, scale;
|
||||
int count;
|
||||
int cells;
|
||||
TimerHandle_t timer;
|
||||
} battery;
|
||||
} battery = {
|
||||
.channel = CONFIG_BAT_CHANNEL,
|
||||
.cells = 2,
|
||||
};
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
@@ -43,6 +47,14 @@ int battery_value_svc(void) {
|
||||
return battery.avg;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
uint8_t battery_level_svc(void) {
|
||||
// TODO: this is totally incorrect
|
||||
return battery.avg ? (battery.avg - (3.0 * battery.cells)) / ((4.2 - 3.0) * battery.cells) * 100 : 0;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
@@ -59,29 +71,30 @@ static void battery_callback(TimerHandle_t xTimer) {
|
||||
*
|
||||
*/
|
||||
void battery_svc_init(void) {
|
||||
battery.channel = CONFIG_BAT_CHANNEL;
|
||||
#ifdef CONFIG_BAT_SCALE
|
||||
battery.scale = atof(CONFIG_BAT_SCALE);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BAT_LOCKED
|
||||
char *nvs_item = config_alloc_get_default(NVS_TYPE_STR, "bat_config", "n", 0);
|
||||
if (nvs_item) {
|
||||
char *p;
|
||||
#ifndef CONFIG_BAT_LOCKED
|
||||
if ((p = strcasestr(nvs_item, "channel")) != NULL) battery.channel = atoi(strchr(p, '=') + 1);
|
||||
if ((p = strcasestr(nvs_item, "scale")) != NULL) battery.scale = atof(strchr(p, '=') + 1);
|
||||
#endif
|
||||
if ((p = strcasestr(nvs_item, "cells")) != NULL) battery.cells = atof(strchr(p, '=') + 1);
|
||||
free(nvs_item);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (battery.channel != -1) {
|
||||
ESP_LOGI(TAG, "Battery measure channel: %u, scale %f", battery.channel, battery.scale);
|
||||
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
adc1_config_channel_atten(battery.channel, ADC_ATTEN_DB_0);
|
||||
|
||||
battery.avg = adc1_get_raw(battery.channel) * battery.scale / 4095.0;
|
||||
battery.timer = xTimerCreate("battery", BATTERY_TIMER / portTICK_RATE_MS, pdTRUE, NULL, battery_callback);
|
||||
xTimerStart(battery.timer, portMAX_DELAY);
|
||||
|
||||
ESP_LOGI(TAG, "Battery measure channel: %u, scale %f, cells %u, avg %.2fV", battery.channel, battery.scale, battery.cells, battery.avg);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "No battery");
|
||||
}
|
||||
|
||||
@@ -17,4 +17,5 @@ extern void (*spkfault_handler_svc)(bool inserted);
|
||||
extern bool spkfault_svc(void);
|
||||
|
||||
extern int battery_value_svc(void);
|
||||
extern uint8_t battery_level_svc(void);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "esp_system.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "monitor.h"
|
||||
|
||||
mutex_type slimp_mutex;
|
||||
|
||||
@@ -60,3 +61,11 @@ u16_t get_RSSI(void) {
|
||||
if (wifidata.primary != 0) return 100 + wifidata.rssi + 30;
|
||||
else return 0xffff;
|
||||
}
|
||||
|
||||
u16_t get_plugged(void) {
|
||||
return jack_inserted_svc() ? PLUG_HEADPHONE : 0;
|
||||
}
|
||||
|
||||
u8_t get_battery(void) {
|
||||
return (battery_level_svc() * 16) / 100;
|
||||
}
|
||||
|
||||
@@ -66,8 +66,13 @@ extern mutex_type slimp_mutex;
|
||||
#define LOCK_P mutex_lock(slimp_mutex)
|
||||
#define UNLOCK_P mutex_unlock(slimp_mutex)
|
||||
|
||||
// must provide or define as 0xffff
|
||||
u16_t get_RSSI(void);
|
||||
// bitmap of plugs status
|
||||
#define PLUG_LINE_IN 0x01
|
||||
#define PLUG_LINE_OUT 0x02
|
||||
#define PLUG_HEADPHONE 0x04
|
||||
u16_t get_RSSI(void); // must provide or define as 0xffff
|
||||
u16_t get_plugged(void); // must provide or define as 0x0
|
||||
u8_t get_battery(void); // must provide 0..15 or define as 0x0
|
||||
|
||||
// to be defined to nothing if you don't want to support these
|
||||
extern struct visu_export_s {
|
||||
|
||||
@@ -31,6 +31,7 @@ sure that using rate_delay would fix that
|
||||
*/
|
||||
|
||||
#include "squeezelite.h"
|
||||
#include "slimproto.h"
|
||||
#include "esp_pthread.h"
|
||||
#include "driver/i2s.h"
|
||||
#include "driver/i2c.h"
|
||||
@@ -82,6 +83,7 @@ const struct adac_s *adac = &dac_external;
|
||||
|
||||
static log_level loglevel;
|
||||
|
||||
static bool (*slimp_handler_chain)(u8_t *data, int len);
|
||||
static bool jack_mutes_amp;
|
||||
static bool running, isI2SStarted;
|
||||
static i2s_config_t i2s_config;
|
||||
@@ -108,6 +110,36 @@ static void (*jack_handler_chain)(bool inserted);
|
||||
|
||||
#define I2C_PORT 0
|
||||
|
||||
/****************************************************************************************
|
||||
* AUDO packet handler
|
||||
*/
|
||||
static bool handler(u8_t *data, int len){
|
||||
bool res = true;
|
||||
|
||||
if (!strncmp((char*) data, "audo", 4)) {
|
||||
struct audo_packet *pkt = (struct audo_packet*) data;
|
||||
// 0 = headphone (internal speakers off), 1 = sub out,
|
||||
// 2 = always on (internal speakers on), 3 = always off
|
||||
|
||||
if (jack_mutes_amp != (pkt->config == 0)) {
|
||||
jack_mutes_amp = pkt->config == 0;
|
||||
config_set_value(NVS_TYPE_STR, "jack_mutes_amp", jack_mutes_amp ? "y" : "n");
|
||||
|
||||
if (jack_mutes_amp && jack_inserted_svc()) adac->speaker(false);
|
||||
else adac->speaker(true);
|
||||
}
|
||||
|
||||
LOG_INFO("got AUDO %02x", pkt->config);
|
||||
} else {
|
||||
res = false;
|
||||
}
|
||||
|
||||
// chain protocol handlers (bitwise or is fine)
|
||||
if (*slimp_handler_chain) res |= (*slimp_handler_chain)(data, len);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* jack insertion handler
|
||||
*/
|
||||
@@ -165,6 +197,10 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
|
||||
char *p;
|
||||
esp_err_t res;
|
||||
|
||||
// chain SLIMP handlers
|
||||
slimp_handler_chain = slimp_handler;
|
||||
slimp_handler = handler;
|
||||
|
||||
p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
|
||||
jack_mutes_amp = (strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0);
|
||||
free(p);
|
||||
|
||||
@@ -190,6 +190,7 @@ static void sendSTAT(const char *event, u32_t server_timestamp) {
|
||||
packN(&pkt.bytes_received_L, (u64_t)status.stream_bytes & 0xffffffff);
|
||||
#if EMBEDDED
|
||||
packn(&pkt.signal_strength, get_RSSI());
|
||||
packn(&pkt.voltage, (get_battery() << 4) | get_plugged());
|
||||
#else
|
||||
pkt.signal_strength = 0xffff;
|
||||
#endif
|
||||
@@ -197,7 +198,6 @@ static void sendSTAT(const char *event, u32_t server_timestamp) {
|
||||
packN(&pkt.output_buffer_size, status.output_size);
|
||||
packN(&pkt.output_buffer_fullness, status.output_full);
|
||||
packN(&pkt.elapsed_seconds, ms_played / 1000);
|
||||
// voltage;
|
||||
packN(&pkt.elapsed_milliseconds, ms_played);
|
||||
pkt.server_timestamp = server_timestamp; // keep this is server format - don't unpack/pack
|
||||
// error_code;
|
||||
|
||||
@@ -178,6 +178,12 @@ struct codc_packet {
|
||||
u8_t pcm_endianness;
|
||||
};
|
||||
|
||||
// initially Boom
|
||||
struct audo_packet {
|
||||
char opcode[4];
|
||||
u8_t config;
|
||||
};
|
||||
|
||||
#ifndef SUN
|
||||
#pragma pack(pop)
|
||||
#else
|
||||
|
||||
@@ -287,8 +287,6 @@ void register_default_nvs(){
|
||||
config_set_default(NVS_TYPE_STR, "a2dp_ctrld", STR(CONFIG_A2DP_CONTROL_DELAY_MS), 0);
|
||||
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bt_sink_pin", STR(CONFIG_A2DP_CONTROL_DELAY_MS));
|
||||
|
||||
|
||||
|
||||
config_set_default(NVS_TYPE_STR, "bt_sink_pin", STR(CONFIG_BT_SINK_PIN), 0);
|
||||
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "release_url", SQUEEZELITE_ESP32_RELEASE_URL);
|
||||
config_set_default(NVS_TYPE_STR, "release_url", SQUEEZELITE_ESP32_RELEASE_URL, 0);
|
||||
@@ -361,6 +359,9 @@ void register_default_nvs(){
|
||||
ESP_LOGD(TAG,"Registering default value for key %s", "dac_controlset");
|
||||
config_set_default(NVS_TYPE_STR, "dac_controlset", "", 0);
|
||||
|
||||
ESP_LOGD(TAG,"Registering default value for key %s", "jack_mutes_amp");
|
||||
config_set_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
|
||||
|
||||
ESP_LOGD(TAG,"Registering default value for key %s", "bat_config");
|
||||
config_set_default(NVS_TYPE_STR, "bat_config", "", 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user