@@ -125,14 +125,17 @@ uint8_t *planebuf1;
125125uint8_t *planebuf2;
126126uint8_t *currentPlaneBuffer;
127127
128+ // tmp buffer for oversampling etc.
129+ uint8_t *processingbuf;
130+
128131// processed frame (merged planes)
129132uint8_t *framebuf1;
130133uint8_t *framebuf2;
131134uint8_t *framebuf3;
132135uint8_t *current_framebuf;
133136uint8_t *framebuf_to_send;
134137
135- uint32_t frame_crc;
138+ uint32_t frame_crc = 0 ;
136139uint32_t crc_previous_frame = 0 ;
137140bool detected_0_1_0_1 = false ;
138141bool detected_1_0_0_0 = false ;
@@ -493,6 +496,8 @@ void dmd_dma_handler() {
493496 uint32_t *planebuf = (uint32_t *)currentPlaneBuffer;
494497 buf32_t *v;
495498 uint32_t res;
499+ // source_dwordsperframe is not the entire frame buffer if plane history is
500+ // used. So only the new plane data is fixed here.
496501 for (int i = 0 ; i < source_dwordsperframe; i++) {
497502 v = (buf32_t *)planebuf;
498503 res = (v->byte3 << 24 ) | (v->byte2 << 16 ) | (v->byte1 << 8 ) | (v->byte0 );
@@ -501,7 +506,7 @@ void dmd_dma_handler() {
501506 }
502507
503508 // Get a 32bit pointer to the frame buffer to handle more pixels at once.
504- uint32_t *framebuf = (uint32_t *)current_framebuf ;
509+ uint32_t *framebuf = (uint32_t *)processingbuf ;
505510
506511 bool source_shiftplanesatmerge = (source_mergeplanes == MERGEPLANES_ADDSHIFT);
507512
@@ -648,12 +653,17 @@ void dmd_dma_handler() {
648653 }
649654 }
650655
656+ memcpy (current_framebuf, processingbuf, loopback ? source_bytes : target_bytes);
657+
651658 frame_crc =
652659 crc32 (0 , current_framebuf, loopback ? source_bytes : target_bytes);
653660
654661 switch_buffers ();
655662
656- frame_received = true ;
663+ if (frame_crc != crc_previous_frame) {
664+ crc_previous_frame = frame_crc;
665+ frame_received = true ;
666+ }
657667}
658668
659669void dmdreader_error_blink (bool no_error) {
@@ -949,21 +959,23 @@ bool dmdreader_init(bool return_on_no_detection) {
949959 plane_bytes = dma_bytes;
950960 }
951961
952- size_t frame_bytes = source_bytes * source_lineoversampling;
962+ size_t processing_bytes = source_bytes * source_lineoversampling;
953963
954964 planebuf1 = alloc_aligned_buffer (plane_bytes, 4 , nullptr );
955965 planebuf2 = alloc_aligned_buffer (plane_bytes, 4 , nullptr );
956- framebuf1 = alloc_aligned_buffer (frame_bytes, 8 , nullptr );
957- framebuf2 = alloc_aligned_buffer (frame_bytes, 8 , nullptr );
966+ processingbuf = alloc_aligned_buffer (processing_bytes, 8 , nullptr );
967+ framebuf1 = alloc_aligned_buffer (source_bytes, 8 , nullptr );
968+ framebuf2 = alloc_aligned_buffer (source_bytes, 8 , nullptr );
958969 framebuf3 = alloc_aligned_buffer (target_bytes, 8 , nullptr );
959970
960- dmdreader_error_blink (planebuf1 && planebuf2 && framebuf1 && framebuf2 &&
961- framebuf3);
971+ dmdreader_error_blink (planebuf1 && planebuf2 && processingbuf &&
972+ framebuf1 && framebuf2 && framebuf3);
962973
963974 memset (planebuf1, 0 , plane_bytes);
964975 memset (planebuf2, 0 , plane_bytes);
965- memset (framebuf1, 0 , frame_bytes);
966- memset (framebuf1, 0 , frame_bytes);
976+ memset (processingbuf, 0 , processing_bytes);
977+ memset (framebuf1, 0 , source_bytes);
978+ memset (framebuf2, 0 , source_bytes);
967979 memset (framebuf3, 0 , target_bytes);
968980 }
969981
@@ -1048,10 +1060,7 @@ void dmdreader_spi_init() {
10481060bool dmdreader_spi_send () {
10491061 if (!loopback && frame_received) {
10501062 frame_received = false ;
1051- if (frame_crc != crc_previous_frame) {
1052- spi_send_pix (framebuf_to_send, frame_crc, true );
1053- crc_previous_frame = frame_crc;
1054- }
1063+ spi_send_pix (framebuf_to_send, frame_crc, true );
10551064
10561065 return true ;
10571066 }
@@ -1067,38 +1076,38 @@ void dmdreader_loopback_init(uint8_t *buffer1, uint8_t *buffer2, Color color) {
10671076 loopback = true ;
10681077}
10691078
1070- void dmdreader_loopback_stop () { loopback = false ; }
1079+ void dmdreader_loopback_stop () {
1080+ free (framebuf3);
1081+ loopback = false ;
1082+ }
10711083
10721084uint8_t *dmdreader_loopback_render () {
10731085 uint64_t *frame4bit = (uint64_t *)framebuf3;
10741086
10751087 if (loopback && frame_received) {
10761088 frame_received = false ;
1077- if (frame_crc != crc_previous_frame) {
1078- crc_previous_frame = frame_crc;
1079- if (current_renderbuf == renderbuf1) {
1080- current_renderbuf = renderbuf2;
1081- } else {
1082- current_framebuf = renderbuf1;
1083- }
1089+ if (current_renderbuf == renderbuf1) {
1090+ current_renderbuf = renderbuf2;
1091+ } else {
1092+ current_framebuf = renderbuf1;
1093+ }
10841094
1085- auto func =
1086- get_optimized_converter (source_width, source_height, monochromeColor);
1087- if (func) {
1088- func ((uint32_t *)framebuf_to_send, current_renderbuf);
1089- if (2 == source_bitsperpixel) {
1090- for (uint16_t i = 0 ; i < source_dwords; i++) {
1091- frame4bit[i] =
1092- convert_2bit_to_4bit_fast (((uint32_t *)framebuf_to_send)[i]);
1093- }
1094- func ((uint32_t *)frame4bit, current_renderbuf);
1095- } else {
1096- func ((uint32_t *)framebuf_to_send, current_renderbuf);
1095+ auto func =
1096+ get_optimized_converter (source_width, source_height, monochromeColor);
1097+ if (func) {
1098+ func ((uint32_t *)framebuf_to_send, current_renderbuf);
1099+ if (2 == source_bitsperpixel) {
1100+ for (uint16_t i = 0 ; i < source_dwords; i++) {
1101+ frame4bit[i] =
1102+ convert_2bit_to_4bit_fast (((uint32_t *)framebuf_to_send)[i]);
10971103 }
1104+ func ((uint32_t *)frame4bit, current_renderbuf);
1105+ } else {
1106+ func ((uint32_t *)framebuf_to_send, current_renderbuf);
10981107 }
1099-
1100- return current_renderbuf;
11011108 }
1109+
1110+ return current_renderbuf;
11021111 }
11031112
11041113 return nullptr ;
0 commit comments