mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 12:37:01 +03:00
display support + extra generic buttons
This commit is contained in:
10
components/display/component.mk
Normal file
10
components/display/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 := .
|
||||||
128
components/display/text.c
Normal file
128
components/display/text.c
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* (c) 2004,2006 Richard Titmuss for SlimProtoLib
|
||||||
|
* (c) 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#define LINELEN 60
|
||||||
|
#define TAG "display"
|
||||||
|
|
||||||
|
//Change special LCD chars to something more printable on screen
|
||||||
|
unsigned char printable(unsigned char c) {
|
||||||
|
switch (c) {
|
||||||
|
case 11: /* block */
|
||||||
|
return '#';
|
||||||
|
break;;
|
||||||
|
case 16: /* rightarrow */
|
||||||
|
return '>';
|
||||||
|
break;;
|
||||||
|
case 22: /* circle */
|
||||||
|
return '@';
|
||||||
|
break;;
|
||||||
|
case 145: /* note */
|
||||||
|
return ' ';
|
||||||
|
break;;
|
||||||
|
case 152: /* bell */
|
||||||
|
return 'o';
|
||||||
|
break;;
|
||||||
|
default:
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace unprintable symbols in line
|
||||||
|
void makeprintable(unsigned char * line) {
|
||||||
|
for (int n=0; n < LINELEN; n++) line[n] = printable(line[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the display
|
||||||
|
void show_display_buffer(char *ddram) {
|
||||||
|
char line1[LINELEN+1];
|
||||||
|
char *line2;
|
||||||
|
|
||||||
|
memset(line1, 0, LINELEN+1);
|
||||||
|
strncpy(line1, ddram, LINELEN);
|
||||||
|
line2 = &(ddram[LINELEN]);
|
||||||
|
line2[LINELEN] = '\0';
|
||||||
|
|
||||||
|
/* Convert special LCD chars */
|
||||||
|
makeprintable((unsigned char *)line1);
|
||||||
|
makeprintable((unsigned char *)line2);
|
||||||
|
ESP_LOGI(TAG, "\n\t%.40s\n\t%.40s", line1, line2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if char is printable, or a valid symbol
|
||||||
|
bool charisok(unsigned char c) {
|
||||||
|
switch (c) {
|
||||||
|
case 11: /* block */
|
||||||
|
case 16: /* rightarrow */
|
||||||
|
case 22: /* circle */
|
||||||
|
case 145: /* note */
|
||||||
|
case 152: /* bell */
|
||||||
|
return true;
|
||||||
|
break;;
|
||||||
|
default:
|
||||||
|
return isprint(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process display data
|
||||||
|
void vfd_data( unsigned short *data, int bytes_read) {
|
||||||
|
unsigned short *display_data;
|
||||||
|
char ddram[LINELEN * 2];
|
||||||
|
int n;
|
||||||
|
int addr = 0; /* counter */
|
||||||
|
|
||||||
|
if (bytes_read % 2) bytes_read--; /* even number of bytes */
|
||||||
|
display_data = &(data[6]); /* display data starts at byte 12 */
|
||||||
|
|
||||||
|
memset(ddram, ' ', LINELEN * 2);
|
||||||
|
for (n=0; n<(bytes_read/2); n++) {
|
||||||
|
unsigned short d; /* data element */
|
||||||
|
unsigned char t, c;
|
||||||
|
|
||||||
|
d = ntohs(display_data[n]);
|
||||||
|
t = (d & 0x00ff00) >> 8; /* type of display data */
|
||||||
|
c = (d & 0x0000ff); /* character/command */
|
||||||
|
switch (t) {
|
||||||
|
case 0x03: /* character */
|
||||||
|
if (!charisok(c)) c = ' ';
|
||||||
|
if (addr <= LINELEN * 2) {
|
||||||
|
ddram[addr++] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x02: /* command */
|
||||||
|
switch (c) {
|
||||||
|
case 0x06: /* display clear */
|
||||||
|
memset(ddram, ' ', LINELEN * 2);
|
||||||
|
break;
|
||||||
|
case 0x02: /* cursor home */
|
||||||
|
addr = 0;
|
||||||
|
break;
|
||||||
|
case 0xc0: /* cursor home2 */
|
||||||
|
addr = LINELEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
show_display_buffer(ddram);
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// BEWARE: this is the index of the array of action below
|
// BEWARE: this is the index of the array of action below
|
||||||
typedef enum { ACTRLS_NONE = -1, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY,
|
typedef enum { ACTRLS_NONE = -1, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY,
|
||||||
ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT,
|
ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT,
|
||||||
|
BCTRLS_PUSH, BCTRLS_UP, BCTRLS_DOWN, BCTRLS_LEFT, BCTRLS_RIGHT,
|
||||||
ACTRLS_MAX
|
ACTRLS_MAX
|
||||||
} actrls_action_e;
|
} actrls_action_e;
|
||||||
typedef void (*actrls_handler)(void);
|
typedef void (*actrls_handler)(void);
|
||||||
|
|||||||
@@ -69,12 +69,35 @@ static void lms_next(void) {
|
|||||||
cli_send_cmd("button fwd");
|
cli_send_cmd("button fwd");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lms_up(void) {
|
||||||
|
cli_send_cmd("button arrow_up");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_down(void) {
|
||||||
|
cli_send_cmd("button arrow_down");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_left(void) {
|
||||||
|
cli_send_cmd("button arrow_left");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_right(void) {
|
||||||
|
cli_send_cmd("button arrow_right");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lms_push(void) {
|
||||||
|
cli_send_cmd("button knob_push");
|
||||||
|
}
|
||||||
|
|
||||||
const actrls_t LMS_controls = {
|
const actrls_t LMS_controls = {
|
||||||
lms_volume_up, lms_volume_down, // volume up, volume down
|
lms_volume_up, lms_volume_down, // volume up, volume down
|
||||||
lms_toggle, lms_play, // toggle, play
|
lms_toggle, lms_play, // toggle, play
|
||||||
lms_pause, lms_stop, // pause, stop
|
lms_pause, lms_stop, // pause, stop
|
||||||
lms_rew, lms_fwd, // rew, fwd
|
lms_rew, lms_fwd, // rew, fwd
|
||||||
lms_prev, lms_next, // prev, next
|
lms_prev, lms_next, // prev, next
|
||||||
|
lms_push,
|
||||||
|
lms_up, lms_down,
|
||||||
|
lms_left, lms_right,
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#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 BASE_CAP "Model=squeezelite,AccuratePlayPoints=0,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")))
|
||||||
|
|
||||||
typedef int16_t s16_t;
|
typedef int16_t s16_t;
|
||||||
@@ -47,6 +47,7 @@ void embedded_init(void);
|
|||||||
void register_external(void);
|
void register_external(void);
|
||||||
void deregister_external(void);
|
void deregister_external(void);
|
||||||
void decode_resume(int external);
|
void decode_resume(int external);
|
||||||
|
void vfd_data(u8_t *data, int len);
|
||||||
|
|
||||||
void (*server_notify)(in_addr_t ip, u16_t hport, u16_t cport);
|
void (*server_notify)(in_addr_t ip, u16_t hport, u16_t cport);
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +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 = 100; // squeezeesp32
|
||||||
|
|
||||||
extern struct buffer *streambuf;
|
extern struct buffer *streambuf;
|
||||||
extern struct buffer *outputbuf;
|
extern struct buffer *outputbuf;
|
||||||
@@ -136,7 +137,7 @@ static void sendHELO(bool reconnect, const char *fixed_cap, const char *var_cap,
|
|||||||
memset(&pkt, 0, sizeof(pkt));
|
memset(&pkt, 0, sizeof(pkt));
|
||||||
memcpy(&pkt.opcode, "HELO", 4);
|
memcpy(&pkt.opcode, "HELO", 4);
|
||||||
pkt.length = htonl(sizeof(struct HELO_packet) - 8 + strlen(base_cap) + strlen(fixed_cap) + strlen(var_cap));
|
pkt.length = htonl(sizeof(struct HELO_packet) - 8 + strlen(base_cap) + strlen(fixed_cap) + strlen(var_cap));
|
||||||
pkt.deviceid = 12; // squeezeplay
|
pkt.deviceid = player_id;
|
||||||
pkt.revision = 0;
|
pkt.revision = 0;
|
||||||
packn(&pkt.wlan_channellist, reconnect ? 0x4000 : 0x0000);
|
packn(&pkt.wlan_channellist, reconnect ? 0x4000 : 0x0000);
|
||||||
packN(&pkt.bytes_received_H, (u64_t)status.stream_bytes >> 32);
|
packN(&pkt.bytes_received_H, (u64_t)status.stream_bytes >> 32);
|
||||||
@@ -444,6 +445,16 @@ static void process_audg(u8_t *pkt, int len) {
|
|||||||
set_volume(audg->adjust ? audg->gainL : FIXED_ONE, audg->adjust ? audg->gainR : FIXED_ONE);
|
set_volume(audg->adjust ? audg->gainL : FIXED_ONE, audg->adjust ? audg->gainR : FIXED_ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void process_dsco(u8_t *pkt, int len) {
|
||||||
|
LOG_INFO("got DSCO, switching from id %u to 12", (int) player_id);
|
||||||
|
player_id = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_vfdc(u8_t *pkt, int len) {
|
||||||
|
LOG_DEBUG("VFDC %u", len);
|
||||||
|
vfd_data( pkt + 4, len - 4);
|
||||||
|
}
|
||||||
|
|
||||||
static void process_setd(u8_t *pkt, int len) {
|
static void process_setd(u8_t *pkt, int len) {
|
||||||
struct setd_packet *setd = (struct setd_packet *)pkt;
|
struct setd_packet *setd = (struct setd_packet *)pkt;
|
||||||
|
|
||||||
@@ -519,6 +530,8 @@ static struct handler handlers[] = {
|
|||||||
{ "audg", process_audg },
|
{ "audg", process_audg },
|
||||||
{ "setd", process_setd },
|
{ "setd", process_setd },
|
||||||
{ "serv", process_serv },
|
{ "serv", process_serv },
|
||||||
|
{ "dsco", process_dsco },
|
||||||
|
{ "vfdc", process_vfdc },
|
||||||
{ "", NULL },
|
{ "", NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
# please read the SDK documents if you need to do this.
|
# please read the SDK documents if you need to do this.
|
||||||
#
|
#
|
||||||
#CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
#CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
||||||
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO
|
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO -DMODEL_NAME=SqueezeESP32
|
||||||
COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../tools
|
COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../tools
|
||||||
COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/components/tools/
|
COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/components/tools/
|
||||||
LDFLAGS += -s
|
LDFLAGS += -s
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ extern void services_init(void);
|
|||||||
static const actrls_config_t board_1[] = {
|
static const actrls_config_t board_1[] = {
|
||||||
// normal long shifted long shifted
|
// normal long shifted long shifted
|
||||||
{ 4, BUTTON_LOW, true, 1000, -1, {ACTRLS_VOLUP, ACTRLS_NONE}, {ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
|
{ 4, BUTTON_LOW, true, 1000, -1, {ACTRLS_VOLUP, ACTRLS_NONE}, {ACTRLS_PREV, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE}, {ACTRLS_NONE, ACTRLS_NONE} },
|
||||||
{ 5, BUTTON_LOW, true, 1000, 4, {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, {ACTRLS_TOGGLE, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE} },
|
{ 5, BUTTON_LOW, true, 1000, 4, {ACTRLS_VOLDOWN, ACTRLS_NONE}, {ACTRLS_NEXT, ACTRLS_NONE}, {ACTRLS_TOGGLE, ACTRLS_NONE}, {BCTRLS_DOWN, ACTRLS_NONE} },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const actrls_config_t board_2[] = {
|
static const actrls_config_t board_2[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user