2nd step of integrating Muse

This commit is contained in:
Philippe G
2022-01-19 00:17:49 -08:00
parent 94fe9b0acf
commit ac7ba228e8
5 changed files with 179 additions and 6 deletions

View File

@@ -0,0 +1,13 @@
# This should be made a pure CMake component but as CMake is even
# more shitty under Windows, backslash in path screws it all
if(CONFIG_MUSE)
message("Compiling for MUSE")
set(src_dirs "muse")
else()
set(src_dirs ".")
endif()
idf_component_register( SRC_DIRS ${src_dirs}
PRIV_REQUIRES services
)

View File

@@ -0,0 +1,3 @@
# weak should do the job but it does not
__attribute__((weak)) void target_init(void) {
}

View File

@@ -0,0 +1,137 @@
/*
YOUR LICENSE
*/
#include <string.h>
#include <esp_log.h>
#include <esp_types.h>
#include <esp_system.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <driver/adc.h>
#include "driver/rmt.h"
#include "monitor.h"
/////////////////////////////////////////////////////////////////
//*********************** NeoPixels ***************************
////////////////////////////////////////////////////////////////
#define NUM_LEDS 1
#define LED_RMT_TX_CHANNEL 0
#define LED_RMT_TX_GPIO 22
#define BITS_PER_LED_CMD 24
#define LED_BUFFER_ITEMS ((NUM_LEDS * BITS_PER_LED_CMD))
// These values are determined by measuring pulse timing with logic analyzer and adjusting to match datasheet.
#define T0H 14 // 0 bit high time
#define T1H 52 // 1 bit high time
#define TL 52 // low time for either bit
#define GREEN 0xFF0000
#define RED 0x00FF00
#define BLUE 0x0000FF
#define WHITE 0xFFFFFF
#define YELLOW 0xE0F060
struct led_state {
uint32_t leds[NUM_LEDS];
};
void ws2812_control_init(void);
void ws2812_write_leds(struct led_state new_state);
///////////////////////////////////////////////////////////////////
static const char TAG[] = "muse";
static void (*battery_handler_chain)(float value);
static void battery(void *data);
static void battery_svc(float value);
void target_init(void) {
battery_handler_chain = battery_handler_svc;
battery_handler_svc = battery_svc;
ESP_LOGI(TAG, "Initializing for Muse");
}
static void battery_svc(float value) {
ESP_LOGI(TAG, "Called for battery service with %f", value);
if (battery_handler_chain) battery_handler_chain(value);
}
// Battery monitoring
static void battery(void *data)
{
#define VGREEN 2300
#define VRED 2000
#define NM 10
static int val;
static int V[NM];
static int I=0;
int S;
for(int i=0;i<NM;i++)V[i]=VGREEN;
vTaskDelay(1000 / portTICK_PERIOD_MS);
struct led_state new_state;
ws2812_control_init();
// init ADC interface for battery survey
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_GPIO33_CHANNEL, ADC_ATTEN_DB_11);
while(true)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
V[I++] = adc1_get_raw(ADC1_GPIO33_CHANNEL);
if(I >= NM)I = 0;
S = 0;
for(int i=0;i<NM;i++)S = S + V[i];
val = S / NM;
new_state.leds[0] = YELLOW;
if(val > VGREEN) new_state.leds[0] = GREEN;
if(val < VRED) new_state.leds[0] = RED;
printf("====> %d %6x\n", val, new_state.leds[0]);
ws2812_write_leds(new_state);
}
}
// This is the buffer which the hw peripheral will access while pulsing the output pin
rmt_item32_t led_data_buffer[LED_BUFFER_ITEMS];
void setup_rmt_data_buffer(struct led_state new_state);
void ws2812_control_init(void)
{
rmt_config_t config;
config.rmt_mode = RMT_MODE_TX;
config.channel = LED_RMT_TX_CHANNEL;
config.gpio_num = LED_RMT_TX_GPIO;
config.mem_block_num = 3;
config.tx_config.loop_en = false;
config.tx_config.carrier_en = false;
config.tx_config.idle_output_en = true;
config.tx_config.idle_level = 0;
config.clk_div = 2;
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
}
void ws2812_write_leds(struct led_state new_state) {
setup_rmt_data_buffer(new_state);
ESP_ERROR_CHECK(rmt_write_items(LED_RMT_TX_CHANNEL, led_data_buffer, LED_BUFFER_ITEMS, false));
ESP_ERROR_CHECK(rmt_wait_tx_done(LED_RMT_TX_CHANNEL, portMAX_DELAY));
}
void setup_rmt_data_buffer(struct led_state new_state)
{
for (uint32_t led = 0; led < NUM_LEDS; led++) {
uint32_t bits_to_send = new_state.leds[led];
uint32_t mask = 1 << (BITS_PER_LED_CMD - 1);
for (uint32_t bit = 0; bit < BITS_PER_LED_CMD; bit++) {
uint32_t bit_is_set = bits_to_send & mask;
led_data_buffer[led * BITS_PER_LED_CMD + bit] = bit_is_set ?
(rmt_item32_t){{{T1H, 1, TL, 0}}} :
(rmt_item32_t){{{T0H, 1, TL, 0}}};
mask >>= 1;
}
}
}

View File

@@ -114,12 +114,16 @@ menu "Squeezelite-ESP32"
config ETH_CONFIG config ETH_CONFIG
string string
default "" default ""
# AGGREGATES - end
config DAC_CONTROLSET config DAC_CONTROLSET
string string
default "{ \"init\": [ {\"reg\":41, \"val\":128}, {\"reg\":18, \"val\":255} ], \"poweron\": [ {\"reg\":18, \"val\":64, \"mode\":\"or\"} ], \"poweroff\": [ {\"reg\":18, \"val\":191, \"mode\":\"and\"} ] }" if TWATCH2020 default "{ \"init\": [ {\"reg\":41, \"val\":128}, {\"reg\":18, \"val\":255} ], \"poweron\": [ {\"reg\":18, \"val\":64, \"mode\":\"or\"} ], \"poweroff\": [ {\"reg\":18, \"val\":191, \"mode\":\"and\"} ] }" if TWATCH2020
default "{\"init\":[ {\"reg\":0,\"val\":128}, {\"reg\":0,\"val\":0}, {\"reg\":25,\"val\":4}, {\"reg\":1,\"val\":80}, {\"reg\":2,\"val\":0}, {\"reg\":8,\"val\":0}, {\"reg\":4,\"val\":192}, {\"reg\":0,\"val\":18}, {\"reg\":1,\"val\":0}, {\"reg\":23,\"val\":24}, {\"reg\":24,\"val\":2}, {\"reg\":38,\"val\":9}, {\"reg\":39,\"val\":144}, {\"reg\":42,\"val\":144}, {\"reg\":43,\"val\":128}, {\"reg\":45,\"val\":128}, {\"reg\":27,\"val\":0}, {\"reg\":26,\"val\":0}, {\"reg\":2,\"val\":240}, {\"reg\":2,\"val\":0}, {\"reg\":29,\"val\":28}, {\"reg\":4,\"val\":48}, {\"reg\":25,\"val\":0} ]}" if MUSE default "{\"init\":[ {\"reg\":0,\"val\":128}, {\"reg\":0,\"val\":0}, {\"reg\":25,\"val\":4}, {\"reg\":1,\"val\":80}, {\"reg\":2,\"val\":0}, {\"reg\":8,\"val\":0}, {\"reg\":4,\"val\":192}, {\"reg\":0,\"val\":18}, {\"reg\":1,\"val\":0}, {\"reg\":23,\"val\":24}, {\"reg\":24,\"val\":2}, {\"reg\":38,\"val\":9}, {\"reg\":39,\"val\":144}, {\"reg\":42,\"val\":144}, {\"reg\":43,\"val\":128}, {\"reg\":45,\"val\":128}, {\"reg\":27,\"val\":0}, {\"reg\":26,\"val\":0}, {\"reg\":2,\"val\":240}, {\"reg\":2,\"val\":0}, {\"reg\":29,\"val\":28}, {\"reg\":4,\"val\":48}, {\"reg\":25,\"val\":0} ]}" if MUSE
default "" default ""
# AGGREGATES - end config AUDIO_CONTROLS
string
default "[{\"gpio\":32, \"pull\":true, \"debounce\":10, \"normal\":{\"pressed\":\"ACTRLS_VOLDOWN\"}}, {\"gpio\":19, \"pull\":true, \"debounce\":40, \"normal\":{\"pressed\":\"ACTRLS_VOLUP\"}}, {\"gpio\":12, \"pull\":true, \"debounce\":40, \"longpress\":1000, \"normal\":{\"pressed\":\"ACTRLS_TOGGLE\"},\"longpress\":{\"pressed\":\"ACTRLS_POWER\"}}]" if MUSE
default ""
endmenu endmenu
menu "Ethernet Options" menu "Ethernet Options"
@@ -286,30 +290,38 @@ menu "Squeezelite-ESP32"
config BT_NAME config BT_NAME
depends on BT_SINK depends on BT_SINK
string "Name of Bluetooth A2DP device" string "Name of Bluetooth A2DP device"
default "ESP32-BT" default "ESP32-BT"
help help
This is the name of the bluetooth speaker that will be broadcasted This is the name of the bluetooth speaker that will be broadcasted
config BT_SINK_PIN config BT_SINK_PIN
depends on BT_SINK depends on BT_SINK
int "Bluetooth PIN code" int "Bluetooth PIN code"
default 1234 default 1234
config AIRPLAY_SINK config AIRPLAY_SINK
bool "AirPlay receiver" bool "AirPlay receiver"
default y default y
config AIRPLAY_NAME config AIRPLAY_NAME
depends on AIRPLAY_SINK depends on AIRPLAY_SINK
string "Name of AirPlay device" string "Name of AirPlay device"
default "ESP32-AirPlay" default "ESP32-AirPlay"
help help
This is the name of the AirPlay speaker that will be broadcasted This is the name of the AirPlay speaker that will be broadcasted
config AIRPLAY_PORT config AIRPLAY_PORT
depends on AIRPLAY_SINK depends on AIRPLAY_SINK
string "AirPlay listening port" string "AirPlay listening port"
default 5000 default 5000
help help
AirPlay service listening port AirPlay service listening port
endmenu endmenu
menu "Controls"
depends on !MUSE
config AUDIO_CONTROLS
string "Audio buttons set (JSON)"
help
Configuration of buttons (see README for syntax)
endmenu
menu "Display Screen" menu "Display Screen"
depends on !TWATCH2020 depends on !TWATCH2020
config DISPLAY_CONFIG config DISPLAY_CONFIG
@@ -355,6 +367,7 @@ menu "Squeezelite-ESP32"
Set parameters of GPIO extender Set parameters of GPIO extender
model=<model>[,addr=<addr>][,base=<100..N>][,count=<0..32>][,intr=<gpio>][,port=dac|system] model=<model>[,addr=<addr>][,base=<100..N>][,count=<0..32>][,intr=<gpio>][,port=dac|system]
endmenu endmenu
menu "LED configuration" menu "LED configuration"
visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE
config LED_GREEN_GPIO config LED_GREEN_GPIO
@@ -381,6 +394,7 @@ menu "Squeezelite-ESP32"
default 0 if SQUEEZEAMP default 0 if SQUEEZEAMP
default 1 default 1
endmenu endmenu
menu "Audio JACK" menu "Audio JACK"
visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE
config JACK_GPIO config JACK_GPIO
@@ -394,6 +408,7 @@ menu "Squeezelite-ESP32"
int "Level when inserted (0/1)" int "Level when inserted (0/1)"
default 0 default 0
endmenu endmenu
menu "Amplifier" menu "Amplifier"
visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE
config AMP_GPIO config AMP_GPIO
@@ -407,6 +422,7 @@ menu "Squeezelite-ESP32"
int "Active level(0/1)" int "Active level(0/1)"
default 1 default 1
endmenu endmenu
menu "Speaker Fault" menu "Speaker Fault"
visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE visible if !SQUEEZEAMP && !TWATCH2020 && !MUSE
config SPKFAULT_GPIO config SPKFAULT_GPIO
@@ -420,6 +436,7 @@ menu "Squeezelite-ESP32"
int "Level when fault (0/1)" int "Level when fault (0/1)"
default 0 default 0
endmenu endmenu
menu "Battery measure" menu "Battery measure"
visible if !SQUEEZEAMP && !TWATCH2020 visible if !SQUEEZEAMP && !TWATCH2020
config BAT_CHANNEL config BAT_CHANNEL

View File

@@ -68,6 +68,7 @@ extern const uint8_t server_cert_pem_end[] asm("_binary_github_pem_end");
// as an exception _init function don't need include // as an exception _init function don't need include
extern void services_init(void); extern void services_init(void);
extern void display_init(char *welcome); extern void display_init(char *welcome);
extern void target_init(void);
const char * str_or_unknown(const char * str) { return (str?str:unknown_string_placeholder); } const char * str_or_unknown(const char * str) { return (str?str:unknown_string_placeholder); }
const char * str_or_null(const char * str) { return (str?str:null_string_placeholder); } const char * str_or_null(const char * str) { return (str?str:null_string_placeholder); }
bool is_recovery_running; bool is_recovery_running;
@@ -474,6 +475,8 @@ void app_main()
ESP_LOGI(TAG,"Initializing display"); ESP_LOGI(TAG,"Initializing display");
display_init("SqueezeESP32"); display_init("SqueezeESP32");
target_init();
if(is_recovery_running && display){ if(is_recovery_running && display){
GDS_ClearExt(display, true); GDS_ClearExt(display, true);
GDS_SetFont(display, &Font_droid_sans_fallback_15x17 ); GDS_SetFont(display, &Font_droid_sans_fallback_15x17 );
@@ -501,7 +504,7 @@ void app_main()
if(!is_recovery_running){ if(!is_recovery_running){
ESP_LOGD(TAG,"Getting audio control mapping "); ESP_LOGD(TAG,"Getting audio control mapping ");
char *actrls_config = config_alloc_get_default(NVS_TYPE_STR, "actrls_config", NULL, 0); char *actrls_config = config_alloc_get_default(NVS_TYPE_STR, "actrls_config", CONFIG_AUDIO_CONTROLS, 0);
if (actrls_init(actrls_config) == ESP_OK) { if (actrls_init(actrls_config) == ESP_OK) {
ESP_LOGD(TAG,"Initializing audio control buttons type %s", actrls_config); ESP_LOGD(TAG,"Initializing audio control buttons type %s", actrls_config);
} else { } else {