handle case w/o display - release

This commit is contained in:
philippe44
2020-01-30 22:48:36 -08:00
parent 9d2aa978d5
commit 5d07344b4d
9 changed files with 55 additions and 22 deletions

View File

@@ -175,7 +175,7 @@ static bool cmd_handler(bt_sink_cmd_t cmd, ...) {
displayer_control(DISPLAYER_TIMER_RUN); displayer_control(DISPLAYER_TIMER_RUN);
break; break;
case BT_SINK_STOP: case BT_SINK_STOP:
// not sure of difference between pause and stop for displayer // not sure of difference between pause and stop for displayer
case BT_SINK_PAUSE: case BT_SINK_PAUSE:
displayer_control(DISPLAYER_TIMER_PAUSE); displayer_control(DISPLAYER_TIMER_PAUSE);
break; break;
@@ -397,7 +397,7 @@ void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_param
bt_av_playback_changed(); bt_av_playback_changed();
break; break;
case ESP_AVRC_RN_PLAY_POS_CHANGED: case ESP_AVRC_RN_PLAY_POS_CHANGED:
ESP_LOGI(BT_AV_TAG, "Play position changed: %d-ms", event_parameter->play_pos); ESP_LOGD(BT_AV_TAG, "Play position changed: %d (ms)", event_parameter->play_pos);
(*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, event_parameter->play_pos, -1); (*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, event_parameter->play_pos, -1);
bt_av_play_pos_changed(); bt_av_play_pos_changed();
break; break;
@@ -440,7 +440,7 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param)
break; break;
} }
case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: {
ESP_LOGI(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id); ESP_LOGD(BT_RC_CT_TAG, "AVRC event notification: %d", rc->change_ntf.event_id);
bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter);
break; break;
} }

View File

@@ -29,7 +29,7 @@
// here we should include all possible drivers // here we should include all possible drivers
extern struct display_s SSD1306_display; extern struct display_s SSD1306_display;
struct display_s *display; struct display_s *display = NULL;
static const char *TAG = "display"; static const char *TAG = "display";
@@ -72,6 +72,7 @@ void display_init(char *welcome) {
init = true; init = true;
ESP_LOGI(TAG, "Display initialization successful"); ESP_LOGI(TAG, "Display initialization successful");
} else { } else {
display = NULL;
ESP_LOGE(TAG, "Display initialization failed"); ESP_LOGE(TAG, "Display initialization failed");
} }
} else { } else {
@@ -103,7 +104,7 @@ void display_init(char *welcome) {
} }
/**************************************************************************************** /****************************************************************************************
* This is not really thread-safe as displayer_task might be in the middle of line drawing * This is not thread-safe as displayer_task might be in the middle of line drawing
* but it won't crash (I think) and making it thread-safe would be complicated for a * but it won't crash (I think) and making it thread-safe would be complicated for a
* feature which is secondary (the LMS version of scrolling is thread-safe) * feature which is secondary (the LMS version of scrolling is thread-safe)
*/ */
@@ -128,11 +129,19 @@ static void displayer_task(void *args) {
if (scroll_sleep <= 10) { if (scroll_sleep <= 10) {
// something to scroll (or we'll wake-up every pause ms ... no big deal) // something to scroll (or we'll wake-up every pause ms ... no big deal)
if (*displayer.string && displayer.state == DISPLAYER_ACTIVE) { if (*displayer.string && displayer.state == DISPLAYER_ACTIVE) {
display->line(2, -displayer.offset, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.string);
xSemaphoreTake(displayer.mutex, portMAX_DELAY); xSemaphoreTake(displayer.mutex, portMAX_DELAY);
// need to work with local copies as we don't want to suspend caller
int offset = -displayer.offset;
char *string = strdup(displayer.string);
scroll_sleep = displayer.offset ? displayer.speed : displayer.pause; scroll_sleep = displayer.offset ? displayer.speed : displayer.pause;
displayer.offset = displayer.offset >= displayer.boundary ? 0 : (displayer.offset + min(displayer.by, displayer.boundary - displayer.offset)); displayer.offset = displayer.offset >= displayer.boundary ? 0 : (displayer.offset + min(displayer.by, displayer.boundary - displayer.offset));
xSemaphoreGive(displayer.mutex); xSemaphoreGive(displayer.mutex);
// now display using safe copies, can be lengthy
display->line(2, offset, DISPLAY_CLEAR | DISPLAY_UPDATE, string);
free(string);
} else { } else {
scroll_sleep = DEFAULT_SLEEP; scroll_sleep = DEFAULT_SLEEP;
} }
@@ -149,8 +158,8 @@ static void displayer_task(void *args) {
displayer.tick = tick; displayer.tick = tick;
displayer.elapsed += elapsed / 1000; displayer.elapsed += elapsed / 1000;
xSemaphoreGive(displayer.mutex); xSemaphoreGive(displayer.mutex);
if (displayer.elapsed < 3600) sprintf(counter, "%2u:%02u", displayer.elapsed / 60, displayer.elapsed % 60); if (displayer.elapsed < 3600) sprintf(counter, "%5u:%02u", displayer.elapsed / 60, displayer.elapsed % 60);
else sprintf(counter, "%2u:%2u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60); else sprintf(counter, "%2u:%02u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60);
display->line(1, DISPLAY_RIGHT, (DISPLAY_CLEAR | DISPLAY_ONLY_EOL) | DISPLAY_UPDATE, counter); display->line(1, DISPLAY_RIGHT, (DISPLAY_CLEAR | DISPLAY_ONLY_EOL) | DISPLAY_UPDATE, counter);
timer_sleep = 1000; timer_sleep = 1000;
} else timer_sleep = max(1000 - elapsed, 0); } else timer_sleep = max(1000 - elapsed, 0);
@@ -171,6 +180,10 @@ void displayer_metadata(char *artist, char *album, char *title) {
char *string = displayer.string, *p; char *string = displayer.string, *p;
int len = SCROLLABLE_SIZE; int len = SCROLLABLE_SIZE;
// need a display!
if (!display) return;
// just do title if there is no config set
if (!displayer.metadata_config) { if (!displayer.metadata_config) {
strncpy(displayer.string, title ? title : "", SCROLLABLE_SIZE); strncpy(displayer.string, title ? title : "", SCROLLABLE_SIZE);
return; return;
@@ -218,7 +231,7 @@ void displayer_metadata(char *artist, char *album, char *title) {
p = strchr(q + 1, '%'); p = strchr(q + 1, '%');
} }
} else { } else {
string = strdup(title ? title : ""); strncpy(string, title ? title : "", SCROLLABLE_SIZE);
} }
// get optional scroll speed // get optional scroll speed
@@ -232,11 +245,13 @@ void displayer_metadata(char *artist, char *album, char *title) {
xSemaphoreGive(displayer.mutex); xSemaphoreGive(displayer.mutex);
} }
/**************************************************************************************** /****************************************************************************************
* *
*/ */
void displayer_scroll(char *string, int speed) { void displayer_scroll(char *string, int speed) {
// need a display!
if (!display) return;
xSemaphoreTake(displayer.mutex, portMAX_DELAY); xSemaphoreTake(displayer.mutex, portMAX_DELAY);
if (speed) displayer.speed = speed; if (speed) displayer.speed = speed;
@@ -252,10 +267,13 @@ void displayer_scroll(char *string, int speed) {
* *
*/ */
void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) { void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) {
// need a display!
if (!display) return;
xSemaphoreTake(displayer.mutex, portMAX_DELAY); xSemaphoreTake(displayer.mutex, portMAX_DELAY);
if (elapsed >= 0) displayer.elapsed = elapsed; if (elapsed >= 0) displayer.elapsed = elapsed / 1000;
if (duration >= 0) displayer.duration = duration; if (duration >= 0) displayer.duration = duration / 1000;
if (displayer.timer) displayer.tick = xTaskGetTickCount(); if (displayer.timer) displayer.tick = xTaskGetTickCount();
xSemaphoreGive(displayer.mutex); xSemaphoreGive(displayer.mutex);
@@ -267,6 +285,8 @@ void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) {
void displayer_control(enum displayer_cmd_e cmd, ...) { void displayer_control(enum displayer_cmd_e cmd, ...) {
va_list args; va_list args;
if (!display) return;
va_start(args, cmd); va_start(args, cmd);
xSemaphoreTake(displayer.mutex, portMAX_DELAY); xSemaphoreTake(displayer.mutex, portMAX_DELAY);

View File

@@ -164,7 +164,7 @@ static bool set_font(int num, enum display_font_e font, int space) {
lines[0].y = lines[0].space; lines[0].y = lines[0].space;
for (int i = 1; i <= num; i++) lines[i].y = lines[i-1].y + lines[i-1].font->Height + lines[i].space; for (int i = 1; i <= num; i++) lines[i].y = lines[i-1].y + lines[i-1].font->Height + lines[i].space;
ESP_LOGI(TAG, "adding line %u at %u (height:%u)", num + 1, lines[num].y, lines[num].font->Height); ESP_LOGI(TAG, "adding line %u at %d (height:%u)", num + 1, lines[num].y, lines[num].font->Height);
if (lines[num].y + lines[num].font->Height > Display.Height) { if (lines[num].y + lines[num].font->Height > Display.Height) {
ESP_LOGW(TAG, "line does not fit display"); ESP_LOGW(TAG, "line does not fit display");

View File

@@ -47,7 +47,7 @@ void SSD1306_FontDrawChar( struct SSD1306_Device* DisplayHandle, char Character,
NullCheck( ( GlyphData = GetCharPtr( DisplayHandle->Font, Character ) ), return ); NullCheck( ( GlyphData = GetCharPtr( DisplayHandle->Font, Character ) ), return );
if ( Character >= DisplayHandle->Font->StartChar || Character <= DisplayHandle->Font->EndChar ) { if ( Character >= DisplayHandle->Font->StartChar && Character <= DisplayHandle->Font->EndChar ) {
/* The first byte in the glyph data is the width of the character in pixels, skip over */ /* The first byte in the glyph data is the width of the character in pixels, skip over */
GlyphData++; GlyphData++;
GlyphColumnLen = RoundUpFontHeight( DisplayHandle->Font ) / 8; GlyphColumnLen = RoundUpFontHeight( DisplayHandle->Font ) / 8;

View File

@@ -207,7 +207,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, va_list args)
ms = ((u64_t) ((_buf_used(outputbuf) - raop_sync.len) / BYTES_PER_FRAME + output.device_frames + output.frames_in_process) * 1000) / RAOP_SAMPLE_RATE - (now - output.updated); ms = ((u64_t) ((_buf_used(outputbuf) - raop_sync.len) / BYTES_PER_FRAME + output.device_frames + output.frames_in_process) * 1000) / RAOP_SAMPLE_RATE - (now - output.updated);
raop_sync.error[raop_sync.idx] = (raop_sync.playtime - now) - ms; raop_sync.error[raop_sync.idx] = (raop_sync.playtime - now) - ms;
sync_nb = SYNC_NB; sync_nb = SYNC_NB;
LOG_INFO("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, raop_sync.error[raop_sync.idx]); LOG_DEBUG("head local:%u, remote:%u (delta:%d)", ms, raop_sync.playtime - now, raop_sync.error[raop_sync.idx]);
LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process); LOG_DEBUG("obuf:%u, sync_len:%u, devframes:%u, inproc:%u", _buf_used(outputbuf), raop_sync.len, output.device_frames, output.frames_in_process);
} }

View File

@@ -137,10 +137,16 @@ static void scroll_task(void* arg);
/**************************************************************************************** /****************************************************************************************
* *
*/ */
void sb_display_init(void) { bool sb_display_init(void) {
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4))); static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4))); static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4)));
// no display, just make sure we won't have requests
if (!display || display->height == 0 || display->width == 0) {
LOG_INFO("no display for LMS");
return false;
}
// need to force height to 32 maximum // need to force height to 32 maximum
display_width = display->width; display_width = display->width;
display_height = min(display->height, 32); display_height = min(display->height, 32);
@@ -163,6 +169,8 @@ void sb_display_init(void) {
notify_chain = server_notify; notify_chain = server_notify;
server_notify = server; server_notify = server;
return true;
} }
/**************************************************************************************** /****************************************************************************************

View File

@@ -50,9 +50,11 @@ uint32_t _gettime_ms_(void) {
} }
extern void sb_controls_init(void); extern void sb_controls_init(void);
extern void sb_display_init(void); extern bool sb_display_init(void);
u8_t custom_player_id = 12;
void embedded_init(void) { void embedded_init(void) {
sb_controls_init(); sb_controls_init();
sb_display_init(); if (sb_display_init()) custom_player_id = 100;
} }

View File

@@ -26,7 +26,10 @@
#define OUTPUT_THREAD_STACK_SIZE 6 * 1024 #define OUTPUT_THREAD_STACK_SIZE 6 * 1024
#define IR_THREAD_STACK_SIZE 6 * 1024 #define IR_THREAD_STACK_SIZE 6 * 1024
#define PLAYER_ID 100 // or can be as simple as #define PLAYER_ID 100
#define PLAYER_ID custom_player_id;
extern u8_t custom_player_id;
#define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION #define BASE_CAP "Model=squeezeesp32,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION
#define EXT_BSS __attribute__((section(".ext_ram.bss"))) #define EXT_BSS __attribute__((section(".ext_ram.bss")))

View File

@@ -45,7 +45,7 @@ static sockfd sock = -1;
static in_addr_t slimproto_ip = 0; static in_addr_t slimproto_ip = 0;
static u16_t slimproto_hport = 9000; static u16_t slimproto_hport = 9000;
static u16_t slimproto_cport = 9090; static u16_t slimproto_cport = 9090;
static u8_t player_id = PLAYER_ID; static u8_t player_id;
extern struct buffer *streambuf; extern struct buffer *streambuf;
extern struct buffer *outputbuf; extern struct buffer *outputbuf;