浏览代码

Validated 256 pixels SSD1326

philippe44 5 年之前
父节点
当前提交
2b924fa425

+ 25 - 8
components/display/SSD132x.c

@@ -162,15 +162,15 @@ static void IRAM_ATTR DrawPixel1Fast( struct GDS_Device* Device, int X, int Y, i
         *FBOffset ^= BIT( 7 - XBit );
     } else {
 		// we might be able to save the 7-Xbit using BitRemap (A0 bit 2)
-        *FBOffset = ( Color == GDS_COLOR_BLACK ) ?  *FBOffset & ~BIT( 7 - XBit ) : *FBOffset | BIT( 7 - XBit );
+        *FBOffset = ( Color == GDS_COLOR_BLACK ) ?  *FBOffset & ~BIT( XBit ) : *FBOffset | BIT( XBit );
     }
 }
 
 static void ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color ) {
 	uint8_t _Color = Color == GDS_COLOR_BLACK ? 0: 0xff;
-	uint8_t Width = Device->Width >> 3;
+	int Width = Device->Width >> 3;
 	uint8_t *optr = Device->Framebuffer;
-
+	
 	for (int r = y1; r <= y2; r++) {
 		int c = x1;
 		// for a row that is not on a boundary, not column opt can be done, so handle all columns on that line
@@ -184,13 +184,28 @@ static void ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int
 }
 
 static void DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color ) {
-	uint8_t *optr = Device->Framebuffer;
-	
 	if (!Height) Height = Device->Height;
 	if (!Width) Width = Device->Width;
+	int DWidth = Device->Width >> 3;
 	
-	// just do bitreverse and if BitRemap works, there will be even nothing to do	
-	for (int i = Height * Width >> 3; --i >= 0;) *optr++ = BitReverseTable256[*Data++];
+	// Two consecutive bits of source data are split over two different bytes of framebuffer
+	for (int c = 0; c < Width; c++) {
+		uint8_t shift = c & 0x07, bit = ~(1 << shift);
+		uint8_t *optr = Device->Framebuffer + (c >> 3);
+		
+		// we need to linearize code to let compiler better optimize
+		for (int r = Height >> 3; --r >= 0;) {
+			uint8_t Byte = BitReverseTable256[*Data++];
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth; Byte >>= 1;
+			*optr = (*optr & bit) | ((Byte & 0x01) << shift); optr += DWidth;
+		}	
+	}
 }
 
 static void SetHFlip( struct GDS_Device* Device, bool On ) { 
@@ -294,6 +309,7 @@ static const struct GDS_Device SSD132x = {
 
 struct GDS_Device* SSD132x_Detect(char *Driver, struct GDS_Device* Device) {
 	uint8_t Model;
+	int Depth;
 	
 	if (strcasestr(Driver, "SSD1326")) Model = SSD1326;
 	else if (strcasestr(Driver, "SSD1327")) Model = SSD1327;
@@ -304,7 +320,8 @@ struct GDS_Device* SSD132x_Detect(char *Driver, struct GDS_Device* Device) {
 	*Device = SSD132x;	
 	((struct PrivateSpace*) Device->Private)->Model = Model;
 		
-	sscanf(Driver, "%*[^:]:%c", &Device->Depth);
+	sscanf(Driver, "%*[^:]:%u", &Depth);
+	Device->Depth = Depth;
 	
 	if (Model == SSD1326 && Device->Depth == 1) {
 		Device->Update = Update1;

+ 2 - 2
components/display/core/gds.c

@@ -95,7 +95,7 @@ void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2,
 			memset( Device->Framebuffer, Color | (Color << 4), Device->FramebufferSize );
 		} else {
 			uint8_t _Color = Color | (Color << 4);
-			uint8_t Width = Device->Width;
+			int Width = Device->Width;
 			uint8_t *optr = Device->Framebuffer;
 			// try to do byte processing as much as possible
 			for (int r = y1; r <= y2; r++) {
@@ -113,7 +113,7 @@ void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2,
 			}
 		}
 	}
-
+	
 	// make sure diplay will do update
 	Device->Dirty = true;
 }

+ 3 - 1
components/display/core/gds_draw.c

@@ -195,11 +195,11 @@ void GDS_DrawBox( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int
 void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color ) {
 	if (!Height) Height = Device->Height;
 	if (!Width) Width = Device->Width;
-	Height >>= 3;
 		
 	if (Device->DrawBitmapCBR) {
 		Device->DrawBitmapCBR( Device, Data, Width, Height, Color );
 	} else if (Device->Depth == 1) {
+		Height >>= 3;
 		// need to do row/col swap and bit-reverse
 		for (int r = 0; r < Height; r++) {
 			uint8_t *optr = Device->Framebuffer + r*Device->Width, *iptr = Data + r;
@@ -211,6 +211,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int
 	} else if (Device->Depth == 4)	{
 		uint8_t *optr = Device->Framebuffer;
 		int LineLen = Device->Width >> 1;
+		Height >>= 3;
 		for (int i = Width * Height, r = 0, c = 0; --i >= 0;) {
 			uint8_t Byte = BitReverseTable256[*Data++];
 			// we need to linearize code to let compiler better optimize
@@ -237,6 +238,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int
 			if (++r == Height) { c++; r = 0; optr = Device->Framebuffer + (c >> 1); }		
 		}
 	} else {
+		Height >>= 3;
 		// don't know bitdepth, use brute-force solution
 		for (int i = Width * Height, r = 0, c = 0; --i >= 0;) {
 			uint8_t Byte = *Data++;

+ 12 - 53
components/raop/raop.c

@@ -44,7 +44,7 @@
 #include "log_util.h"
 
 #define RTSP_STACK_SIZE 	(8*1024)
-#define SEARCH_STACK_SIZE	(2*1048)
+#define SEARCH_STACK_SIZE	(3*1048)
 
 typedef struct raop_ctx_s {
 #ifdef WIN32
@@ -86,7 +86,7 @@ typedef struct raop_ctx_s {
 		struct mDNShandle_s *handle;
 		pthread_t thread;
 #else
-		TaskHandle_t thread, joiner;
+		TaskHandle_t thread;
 		StaticTask_t *xTaskBuffer;
 		StackType_t xStack[SEARCH_STACK_SIZE] __attribute__ ((aligned (4)));;
 		SemaphoreHandle_t destroy_mutex;
@@ -100,7 +100,7 @@ extern log_level	raop_loglevel;
 static log_level 	*loglevel = &raop_loglevel;
 
 static void*	rtsp_thread(void *arg);
-static void		abort_rtsp(raop_ctx_t *ctx);
+static void		cleanup_rtsp(raop_ctx_t *ctx, bool abort);
 static bool 	handle_rtsp(raop_ctx_t *ctx, int sock);
 
 static char*	rsa_apply(unsigned char *input, int inlen, int *outlen, int mode);
@@ -248,18 +248,6 @@ void raop_delete(struct raop_ctx_s *ctx) {
 	mdns_service_remove(ctx->svr, ctx->svc);
 	mdnsd_stop(ctx->svr);
 #else 
-	// first stop the search task if any
-	if (ctx->active_remote.running) {
-		ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
-		ctx->active_remote.running = false;
-
-		vTaskResume(ctx->active_remote.thread);
-		ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
-		vTaskDelete(ctx->active_remote.thread);
-
-		heap_caps_free(ctx->active_remote.xTaskBuffer);
-	}
-
 	// then the RTSP task
 	ctx->joiner = xTaskGetCurrentTaskHandle();
 	ctx->running = false;
@@ -268,10 +256,11 @@ void raop_delete(struct raop_ctx_s *ctx) {
 	vTaskDelete(ctx->thread);
 	heap_caps_free(ctx->xTaskBuffer);
 
-	rtp_end(ctx->rtp);
-
 	shutdown(ctx->sock, SHUT_RDWR);
 	closesocket(ctx->sock);
+	
+	// cleanup all session-created items
+	cleanup_rtsp(ctx, true);
 		
 	mdns_service_remove("_raop", "_tcp");	
 #endif
@@ -406,7 +395,7 @@ static void *rtsp_thread(void *arg) {
 		if (n > 0) res = handle_rtsp(ctx, sock);
 
 		if (n < 0 || !res || ctx->abort) {
-			abort_rtsp(ctx);
+			cleanup_rtsp(ctx, true);
 			closesocket(sock);
 			LOG_INFO("RTSP close %u", sock);
 			sock = -1;
@@ -581,37 +570,11 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
 		if ((p = strcasestr(buf, "rtptime")) != NULL) sscanf(p, "%*[^=]=%u", &rtptime);
 
 		// only send FLUSH if useful (discards frames above buffer head and top)
-		if (ctx->rtp && rtp_flush(ctx->rtp, seqno, rtptime))
-			success = ctx->cmd_cb(RAOP_FLUSH);
+		if (ctx->rtp && rtp_flush(ctx->rtp, seqno, rtptime)) success = ctx->cmd_cb(RAOP_FLUSH);
 
 	}  else if (!strcmp(method, "TEARDOWN")) {
 
-		rtp_end(ctx->rtp);
-
-		ctx->rtp = NULL;
-
-		// need to make sure no search is on-going and reclaim pthread memory
-#ifdef WIN32
-		if (ctx->active_remote.handle) close_mDNS(ctx->active_remote.handle);
-		pthread_join(ctx->active_remote.thread, NULL);
-#else
-		ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
-		ctx->active_remote.running = false;
-
-		xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
-		vTaskDelete(ctx->active_remote.thread);
-		vSemaphoreDelete(ctx->active_remote.thread);
-		
-		heap_caps_free(ctx->active_remote.xTaskBuffer);
-		
-		LOG_INFO("[%p]: mDNS search task terminated", ctx);
-#endif
-
-		memset(&ctx->active_remote, 0, sizeof(ctx->active_remote));
-		NFREE(ctx->rtsp.aeskey);
-		NFREE(ctx->rtsp.aesiv);
-		NFREE(ctx->rtsp.fmtp);
-
+		cleanup_rtsp(ctx, false);
 		success = ctx->cmd_cb(RAOP_STOP);
 
 	} else if (!strcmp(method, "SET_PARAMETER")) {
@@ -681,12 +644,12 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock)
 }
 
 /*----------------------------------------------------------------------------*/
-void abort_rtsp(raop_ctx_t *ctx) {
+void cleanup_rtsp(raop_ctx_t *ctx, bool abort) {
 	// first stop RTP process
 	if (ctx->rtp) {
 		rtp_end(ctx->rtp);
 		ctx->rtp = NULL;
-		LOG_INFO("[%p]: RTP thread aborted", ctx);
+		if (abort) LOG_INFO("[%p]: RTP thread aborted", ctx);
 	}
 
 	if (ctx->active_remote.running) {
@@ -695,9 +658,7 @@ void abort_rtsp(raop_ctx_t *ctx) {
 		close_mDNS(ctx->active_remote.handle);
 #else
 		// need to make sure no search is on-going and reclaim task memory
-		ctx->active_remote.joiner = xTaskGetCurrentTaskHandle();
 		ctx->active_remote.running = false;
-
 		xSemaphoreTake(ctx->active_remote.destroy_mutex, portMAX_DELAY);
 		vTaskDelete(ctx->active_remote.thread);
 		vSemaphoreDelete(ctx->active_remote.thread);
@@ -705,8 +666,6 @@ void abort_rtsp(raop_ctx_t *ctx) {
 		heap_caps_free(ctx->active_remote.xTaskBuffer);
 #endif
 		memset(&ctx->active_remote, 0, sizeof(ctx->active_remote));
-
-
 		LOG_INFO("[%p]: Remote search thread aborted", ctx);
 	}	
 
@@ -776,7 +735,7 @@ static void* search_remote(void *args) {
 				LOG_INFO("found remote %s %s:%hu", r->instance_name, inet_ntoa(ctx->active_remote.host), ctx->active_remote.port);
 			}
 		}
-	
+
 		mdns_query_results_free(results);
 	}
 

+ 3 - 2
components/squeezelite/display.c

@@ -151,7 +151,7 @@ static EXT_RAM_ATTR struct {
 #define ANIM_SCREEN_2     0x08 
 
 static u8_t ANIC_resp = ANIM_NONE;
-static u8_t SETD_width;
+static uint16_t SETD_width;
 
 #define SCROLL_STACK_SIZE	(3*1024)
 #define LINELEN				40
@@ -316,8 +316,9 @@ static void send_server(void) {
 		pkt_header.id = 0xfe; // id 0xfe is width S:P:Squeezebox2
 		pkt_header.length = htonl(sizeof(pkt_header) +  2 - 8);
 
+		SETD_width = htons(SETD_width);
 		send_packet((u8_t *)&pkt_header, sizeof(pkt_header));
-		send_packet(&SETD_width, 2);
+		send_packet((uint8_t*) &SETD_width, 2);
 
 		SETD_width = 0;
 	}