浏览代码

display support + extra generic buttons

philippe44 5 年之前
父节点
当前提交
4a08f1c5c5

+ 10 - 0
components/display/component.mk

@@ -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 - 0
components/display/text.c

@@ -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);
+}

+ 1 - 0
components/services/audio_controls.h

@@ -23,6 +23,7 @@
 // BEWARE: this is the index of the array of action below
 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, 
+				BCTRLS_PUSH, BCTRLS_UP, BCTRLS_DOWN, BCTRLS_LEFT, BCTRLS_RIGHT,
 				ACTRLS_MAX 
 		} actrls_action_e;
 typedef void (*actrls_handler)(void);

+ 23 - 0
components/squeezelite/controls.c

@@ -69,12 +69,35 @@ static void lms_next(void) {
 	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 = {
 	lms_volume_up, lms_volume_down,	// volume up, volume down
 	lms_toggle, lms_play,	// toggle, play
 	lms_pause, lms_stop,	// pause, stop
 	lms_rew, lms_fwd,		// rew, fwd
 	lms_prev, lms_next,		// prev, next
+	lms_push, 
+	lms_up, lms_down,
+	lms_left, lms_right, 
 };
 
 /****************************************************************************************

+ 2 - 1
components/squeezelite/embedded.h

@@ -25,7 +25,7 @@
 #define OUTPUT_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"))) 
 
 typedef int16_t   s16_t;
@@ -47,6 +47,7 @@ void		embedded_init(void);
 void 		register_external(void);
 void 		deregister_external(void);
 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);
 				   

+ 14 - 1
components/squeezelite/slimproto.c

@@ -45,6 +45,7 @@ static sockfd sock = -1;
 static in_addr_t slimproto_ip = 0;
 static u16_t slimproto_hport = 9000;
 static u16_t slimproto_cport = 9090;
+static u8_t	player_id = 100; // squeezeesp32
 
 extern struct buffer *streambuf;
 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));
 	memcpy(&pkt.opcode, "HELO", 4);
 	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;
 	packn(&pkt.wlan_channellist, reconnect ? 0x4000 : 0x0000);
 	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);
 }
 
+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) {
 	struct setd_packet *setd = (struct setd_packet *)pkt;
 
@@ -519,6 +530,8 @@ static struct handler handlers[] = {
 	{ "audg", process_audg },
 	{ "setd", process_setd },
 	{ "serv", process_serv },
+	{ "dsco", process_dsco },
+	{ "vfdc", process_vfdc },
 	{ "",     NULL  },
 };
 

+ 1 - 1
main/component.mk

@@ -7,7 +7,7 @@
 # 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_INFO
+CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO -DMODEL_NAME=SqueezeESP32
 COMPONENT_ADD_INCLUDEDIRS += $(COMPONENT_PATH)/../tools
 COMPONENT_EXTRA_INCLUDES += $(PROJECT_PATH)/components/tools/
 LDFLAGS += -s

+ 1 - 1
main/esp_app_main.c

@@ -81,7 +81,7 @@ extern void services_init(void);
 static const actrls_config_t board_1[] = {
 	//								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} },
-	{ 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[] = {