浏览代码

more display tweaks

philippe44 5 年之前
父节点
当前提交
dc392b342f

+ 1 - 1
components/squeezelite/decode_external.c

@@ -339,7 +339,7 @@ void deregister_external(void) {
 	}
 }
 
-void decode_resume(int external) {
+void decode_restore(int external) {
 	switch (external) {
 	case DECODE_BT:
 		bt_disconnect();

+ 60 - 23
components/squeezelite/display.c

@@ -53,6 +53,12 @@ struct grfg_packet {
 	u16_t  width;		// # of pixels of scrollable
 };
 
+struct ANIC_header {
+	char  opcode[4];
+	u32_t length;
+	u8_t mode;
+};
+
 #pragma pack(pop)
 
 static struct scroller_s {
@@ -69,30 +75,28 @@ static struct scroller_s {
 	int scroll_len, scroll_step;
 } scroller;
 
-/*
-	ANIM_SCREEN_1                    => end of first scroll on screen 1
-	ANIM_SCREEN_2                    => end of first scroll on screen 2
-	ANIM_SCROLL_ONCE | ANIM_SCREEN_1 => end of scroll once on screen 1
-	ANIM_SCROLL_ONCE | ANIM_SCREEN_2 => end of scroll once on screen 2
-*/	
+#define ANIM_NONE		  0x00
 #define ANIM_TRANSITION   0x01 // A transition animation has finished
 #define ANIM_SCROLL_ONCE  0x02 
 #define ANIM_SCREEN_1     0x04 
 #define ANIM_SCREEN_2     0x08 
 
-#define SCROLL_STACK_SIZE	2048
+static u8_t ANIC_resp = ANIM_NONE;
 
+#define SCROLL_STACK_SIZE	2048
 #define LINELEN				40
-#define HEIGHT				32
 
 static log_level loglevel = lINFO;
 static SemaphoreHandle_t display_sem;
 static bool (*slimp_handler_chain)(u8_t *data, int len);
+static void (*slimp_loop_chain)(void);
 static void (*notify_chain)(in_addr_t ip, u16_t hport, u16_t cport);
+static int display_width, display_height;
 
 #define max(a,b) (((a) > (b)) ? (a) : (b))
 
 static void server(in_addr_t ip, u16_t hport, u16_t cport);
+static void send_server(void);
 static bool handler(u8_t *data, int len);
 static void vfdc_handler( u8_t *_data, int bytes_read);
 static void grfe_handler( u8_t *data, int len);
@@ -135,23 +139,55 @@ void sb_display_init(void) {
 	static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
 	static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4)));
 	
+	// need to force height to 32 maximum
+	display_width = display->width;
+	display_height = min(display->height, 32);
+	
 	// create scroll management task
 	display_sem = xSemaphoreCreateMutex();
 	scroller.task = xTaskCreateStatic( (TaskFunction_t) scroll_task, "scroll_thread", SCROLL_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
 	
 	// size scroller
-	scroller.max = (display->width * display->height / 8) * 10;
+	scroller.max = (display_width * display_height / 8) * 10;
 	scroller.scroll_frame = malloc(scroller.max);
-	scroller.back_frame = malloc(display->width * display->height / 8);
+	scroller.back_frame = malloc(display_width * display_height / 8);
 
 	// chain handlers
 	slimp_handler_chain = slimp_handler;
 	slimp_handler = handler;
 	
+	slimp_loop_chain = slimp_loop;
+	slimp_loop = send_server;
+	
 	notify_chain = server_notify;
 	server_notify = server;
 }
 
+/****************************************************************************************
+ * Send message to server (ANIC at that time)
+ */
+static void send_server(void) {
+	/* 
+	 This complication is needed as we cannot send direclty to LMS, because 
+	 send_packet is not thread safe. So must subscribe to slimproto busy loop
+	 end send from there
+	*/ 
+	if (ANIC_resp != ANIM_NONE) {
+		struct ANIC_header pkt_header;
+
+		memset(&pkt_header, 0, sizeof(pkt_header));
+		memcpy(&pkt_header.opcode, "ANIC", 4);
+		pkt_header.length = htonl(sizeof(pkt_header) - 8);
+		pkt_header.mode = ANIC_resp;
+
+		send_packet((u8_t *)&pkt_header, sizeof(pkt_header));
+		
+		ANIC_resp = ANIM_NONE;
+	}	
+	
+	if (slimp_loop_chain) (*slimp_loop_chain)();
+}
+
 /****************************************************************************************
  * 
  */
@@ -307,7 +343,7 @@ static void grfe_handler( u8_t *data, int len) {
 	xSemaphoreTake(display_sem, portMAX_DELAY);
 	
 	scroller.active = false;
-	display->draw_cbr(data + sizeof(struct grfe_packet), HEIGHT);
+	display->draw_cbr(data + sizeof(struct grfe_packet), display_height);
 	
 	xSemaphoreGive(display_sem);
 	
@@ -393,13 +429,13 @@ static void grfg_handler(u8_t *data, int len) {
 
 	// can't be in grfs as we need full size & scroll_width
 	if (scroller.updated) {
-		scroller.scroll_len = display->width * display->height / 8 - (display->width - scroller.window_width) * display->height / 8;
+		scroller.scroll_len = display_width * display_height / 8 - (display_width - scroller.window_width) * display_height / 8;
 		if (scroller.direction == 1) {
 			scroller.scroll_ptr = scroller.scroll_frame; 
-			scroller.scroll_step = scroller.by * display->height / 8;
+			scroller.scroll_step = scroller.by * display_height / 8;
 		} else	{
 			scroller.scroll_ptr = scroller.scroll_frame + scroller.size - scroller.scroll_len;
-			scroller.scroll_step = -scroller.by * display->height / 8;
+			scroller.scroll_step = -scroller.by * display_height / 8;
 		}
 		
 		scroller.updated = false;	
@@ -407,10 +443,10 @@ static void grfg_handler(u8_t *data, int len) {
 	
 	if (!scroller.active) {
 		// this is a background update and scroller has been finished, so need to update here
-		u8_t *frame = malloc(display->width * display->height / 8);
-		memcpy(frame, scroller.back_frame, display->width * display->height / 8);
+		u8_t *frame = malloc(display_width * display_height / 8);
+		memcpy(frame, scroller.back_frame, display_width * display_height / 8);
 		for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i];
-		display->draw_cbr(frame, HEIGHT);		
+		display->draw_cbr(frame, display_height);		
 		free(frame);
 		LOG_DEBUG("direct drawing");
 	}	
@@ -428,7 +464,7 @@ static void grfg_handler(u8_t *data, int len) {
  */
 static void scroll_task(void *args) {
 	u8_t *frame = NULL;
-	int len = display->width * display->height / 8;
+	int len = display_width * display_height / 8;
 	
 	while (1) {
 		xSemaphoreTake(display_sem, portMAX_DELAY);
@@ -441,7 +477,7 @@ static void scroll_task(void *args) {
 		}	
 		
 		// lock screen & active status
-		frame = malloc(display->width * display->height / 8);
+		frame = malloc(display_width * display_height / 8);
 				
 		// scroll required amount of columns (within the window)
 		while (scroller.direction == 1 ? (scroller.scroll_ptr <= scroller.scroll_frame + scroller.size - scroller.scroll_step - len) :
@@ -451,10 +487,10 @@ static void scroll_task(void *args) {
 			if (!scroller.active) break;
 					
 			// scroll required amount of columns (within the window)
-			memcpy(frame, scroller.back_frame, display->width * display->height / 8);
+			memcpy(frame, scroller.back_frame, display_width * display_height / 8);
 			for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i];
 			scroller.scroll_ptr += scroller.scroll_step;
-			display->draw_cbr(frame, HEIGHT);		
+			display->draw_cbr(frame, display_height);		
 			
 			xSemaphoreGive(display_sem);
 			usleep(scroller.speed * 1000);
@@ -468,14 +504,15 @@ static void scroll_task(void *args) {
 		if (scroller.active) {
 			memcpy(frame, scroller.back_frame, len);
 			for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i];
-			display->draw_cbr(frame, HEIGHT);
+			display->draw_cbr(frame, display_height);
 			free(frame);
 
 			// see if we need to pause or if we are done 				
 			if (scroller.mode) {
 				scroller.active = false;
 				xSemaphoreGive(display_sem);
-				//sendANIC(ANIM_SCROLL_ONCE | ANIM_SCREEN_1);
+				// can't call directly send_packet from slimproto as it's not re-entrant
+				ANIC_resp = ANIM_SCROLL_ONCE | ANIM_SCREEN_1;
 				LOG_INFO("scroll-once terminated");
 			} else {
 				xSemaphoreGive(display_sem);

+ 3 - 2
components/squeezelite/embedded.h

@@ -49,10 +49,11 @@ int			pthread_create_name(pthread_t *thread, _CONST pthread_attr_t  *attr,
 void		embedded_init(void);
 void 		register_external(void);
 void 		deregister_external(void);
-void 		decode_resume(int external);
+void 		decode_restore(int external);
 
-// optional, please chain 
+// optional, please chain if used 
 bool		(*slimp_handler)(u8_t *data, int len);
+void 		(*slimp_loop)(void);
 void 		(*server_notify)(in_addr_t ip, u16_t hport, u16_t cport);
 				   
 #endif // EMBEDDED_H

+ 8 - 7
components/squeezelite/slimproto.c

@@ -87,13 +87,13 @@ static struct {
 	stream_state stream_state;
 } status;
 
-int autostart;
-bool sentSTMu, sentSTMo, sentSTMl;
-u32_t new_server;
-char *new_server_cap;
+static int autostart;
+static bool sentSTMu, sentSTMo, sentSTMl;
+static u32_t new_server;
+static char *new_server_cap;
 #define PLAYER_NAME_LEN 64
-char player_name[PLAYER_NAME_LEN + 1] = "";
-const char *name_file = NULL;
+static char player_name[PLAYER_NAME_LEN + 1] = "";
+static const char *name_file = NULL;
 
 void send_packet(u8_t *packet, size_t len) {
 	u8_t *ptr = packet;
@@ -377,7 +377,7 @@ static void process_strm(u8_t *pkt, int len) {
 			sentSTMu = sentSTMo = sentSTMl = false;
 			LOCK_O;
 #if EMBEDDED
-			if (output.external) decode_resume(output.external);
+			if (output.external) decode_restore(output.external);
 			output.external = 0;
 			_buf_resize(outputbuf, output.init_size);
 #endif
@@ -770,6 +770,7 @@ static void slimproto_run() {
 #if IR
 			if (_sendIR)   sendIR(ir_code, ir_ts);
 #endif
+			if (*slimp_loop) (*slimp_loop)();
 		}
 	}
 }

+ 1 - 0
components/squeezelite/squeezelite.h

@@ -553,6 +553,7 @@ void buf_destroy(struct buffer *buf);
 void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate);
 void slimproto_stop(void);
 void wake_controller(void);
+void send_packet(u8_t *packet, size_t len);
 
 // stream.c
 typedef enum { STOPPED = 0, DISCONNECT, STREAMING_WAIT,