headphone, bass/treble, battery from LMS

This commit is contained in:
Philippe G
2020-08-15 18:43:02 -07:00
parent 19a53fafd3
commit 86b64d0415
9 changed files with 87 additions and 15 deletions

1
TODO
View File

@@ -2,3 +2,4 @@
although they are almost static (expect output). This creates a risk of although they are almost static (expect output). This creates a risk of
memory fragmentation, especially because the large output is re-allocated for memory fragmentation, especially because the large output is re-allocated for
AirPlay AirPlay
- libflac in lpc.c can be unrolled - that gains 43k of code, at the expense of 4% CPU

View File

@@ -33,16 +33,28 @@ static struct {
int channel; int channel;
float sum, avg, scale; float sum, avg, scale;
int count; int count;
int cells;
TimerHandle_t timer; TimerHandle_t timer;
} battery; } battery = {
.channel = CONFIG_BAT_CHANNEL,
.cells = 2,
};
/**************************************************************************************** /****************************************************************************************
* *
*/ */
int battery_value_svc(void) { int battery_value_svc(void) {
return battery.avg; 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) { void battery_svc_init(void) {
battery.channel = CONFIG_BAT_CHANNEL;
#ifdef CONFIG_BAT_SCALE #ifdef CONFIG_BAT_SCALE
battery.scale = atof(CONFIG_BAT_SCALE); battery.scale = atof(CONFIG_BAT_SCALE);
#endif #endif
#ifndef CONFIG_BAT_LOCKED
char *nvs_item = config_alloc_get_default(NVS_TYPE_STR, "bat_config", "n", 0); char *nvs_item = config_alloc_get_default(NVS_TYPE_STR, "bat_config", "n", 0);
if (nvs_item) { if (nvs_item) {
char *p; char *p;
#ifndef CONFIG_BAT_LOCKED
if ((p = strcasestr(nvs_item, "channel")) != NULL) battery.channel = atoi(strchr(p, '=') + 1); 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); 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); free(nvs_item);
} }
#endif
if (battery.channel != -1) { 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_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(battery.channel, ADC_ATTEN_DB_0); 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); battery.timer = xTimerCreate("battery", BATTERY_TIMER / portTICK_RATE_MS, pdTRUE, NULL, battery_callback);
xTimerStart(battery.timer, portMAX_DELAY); 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 { } else {
ESP_LOGI(TAG, "No battery"); ESP_LOGI(TAG, "No battery");
} }

View File

@@ -17,4 +17,5 @@ extern void (*spkfault_handler_svc)(bool inserted);
extern bool spkfault_svc(void); extern bool spkfault_svc(void);
extern int battery_value_svc(void); extern int battery_value_svc(void);
extern uint8_t battery_level_svc(void);

View File

@@ -14,6 +14,7 @@
#include "esp_system.h" #include "esp_system.h"
#include "esp_timer.h" #include "esp_timer.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "monitor.h"
mutex_type slimp_mutex; mutex_type slimp_mutex;
@@ -60,3 +61,11 @@ u16_t get_RSSI(void) {
if (wifidata.primary != 0) return 100 + wifidata.rssi + 30; if (wifidata.primary != 0) return 100 + wifidata.rssi + 30;
else return 0xffff; 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;
}

View File

@@ -66,8 +66,13 @@ extern mutex_type slimp_mutex;
#define LOCK_P mutex_lock(slimp_mutex) #define LOCK_P mutex_lock(slimp_mutex)
#define UNLOCK_P mutex_unlock(slimp_mutex) #define UNLOCK_P mutex_unlock(slimp_mutex)
// must provide or define as 0xffff // bitmap of plugs status
u16_t get_RSSI(void); #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 // to be defined to nothing if you don't want to support these
extern struct visu_export_s { extern struct visu_export_s {

View File

@@ -31,6 +31,7 @@ sure that using rate_delay would fix that
*/ */
#include "squeezelite.h" #include "squeezelite.h"
#include "slimproto.h"
#include "esp_pthread.h" #include "esp_pthread.h"
#include "driver/i2s.h" #include "driver/i2s.h"
#include "driver/i2c.h" #include "driver/i2c.h"
@@ -82,6 +83,7 @@ const struct adac_s *adac = &dac_external;
static log_level loglevel; static log_level loglevel;
static bool (*slimp_handler_chain)(u8_t *data, int len);
static bool jack_mutes_amp; static bool jack_mutes_amp;
static bool running, isI2SStarted; static bool running, isI2SStarted;
static i2s_config_t i2s_config; static i2s_config_t i2s_config;
@@ -108,6 +110,36 @@ static void (*jack_handler_chain)(bool inserted);
#define I2C_PORT 0 #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 * jack insertion handler
*/ */
@@ -165,6 +197,10 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
char *p; char *p;
esp_err_t res; 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); p = config_alloc_get_default(NVS_TYPE_STR, "jack_mutes_amp", "n", 0);
jack_mutes_amp = (strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0); jack_mutes_amp = (strcmp(p,"1") == 0 ||strcasecmp(p,"y") == 0);
free(p); free(p);

View File

@@ -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); packN(&pkt.bytes_received_L, (u64_t)status.stream_bytes & 0xffffffff);
#if EMBEDDED #if EMBEDDED
packn(&pkt.signal_strength, get_RSSI()); packn(&pkt.signal_strength, get_RSSI());
packn(&pkt.voltage, (get_battery() << 4) | get_plugged());
#else #else
pkt.signal_strength = 0xffff; pkt.signal_strength = 0xffff;
#endif #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_size, status.output_size);
packN(&pkt.output_buffer_fullness, status.output_full); packN(&pkt.output_buffer_fullness, status.output_full);
packN(&pkt.elapsed_seconds, ms_played / 1000); packN(&pkt.elapsed_seconds, ms_played / 1000);
// voltage;
packN(&pkt.elapsed_milliseconds, ms_played); packN(&pkt.elapsed_milliseconds, ms_played);
pkt.server_timestamp = server_timestamp; // keep this is server format - don't unpack/pack pkt.server_timestamp = server_timestamp; // keep this is server format - don't unpack/pack
// error_code; // error_code;

View File

@@ -178,6 +178,12 @@ struct codc_packet {
u8_t pcm_endianness; u8_t pcm_endianness;
}; };
// initially Boom
struct audo_packet {
char opcode[4];
u8_t config;
};
#ifndef SUN #ifndef SUN
#pragma pack(pop) #pragma pack(pop)
#else #else

View File

@@ -287,8 +287,6 @@ void register_default_nvs(){
config_set_default(NVS_TYPE_STR, "a2dp_ctrld", STR(CONFIG_A2DP_CONTROL_DELAY_MS), 0); 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)); 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); 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); 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); 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"); ESP_LOGD(TAG,"Registering default value for key %s", "dac_controlset");
config_set_default(NVS_TYPE_STR, "dac_controlset", "", 0); 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"); ESP_LOGD(TAG,"Registering default value for key %s", "bat_config");
config_set_default(NVS_TYPE_STR, "bat_config", "", 0); config_set_default(NVS_TYPE_STR, "bat_config", "", 0);