Skip to content

Commit 82bbecf

Browse files
authored
Merge pull request #1215 from makermelissa/master
Adding Bad Apple Example for Sharp Display
2 parents b3ed5fd + bc26b3b commit 82bbecf

File tree

8 files changed

+736
-1
lines changed

8 files changed

+736
-1
lines changed

SHARP_BadApple/.metro_m4.test.only

Whitespace-only changes.

SHARP_BadApple/SHARP_BadApple.ino

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// Bad Apple for ESP32 with OLED SSD1306 | 2018 by Hackerspace-FFM.de | MIT-License.
2+
// Adapted for Sharp Memory display + Itsy Bitsy M4 - put video.hs on QSPI storage using CircuitPython
3+
#include "heatshrink_decoder.h"
4+
5+
#include "SdFat.h"
6+
#include "Adafruit_SPIFlash.h"
7+
#include <Adafruit_SharpMem.h>
8+
#define BLACK 0
9+
#define WHITE 1
10+
11+
#define SCALE 3
12+
13+
14+
#if HEATSHRINK_DYNAMIC_ALLOC
15+
#error HEATSHRINK_DYNAMIC_ALLOC must be false for static allocation test suite.
16+
#endif
17+
18+
static heatshrink_decoder hsd;
19+
20+
// global storage for putPixels
21+
int16_t curr_x = 0;
22+
int16_t curr_y = 0;
23+
24+
// global storage for decodeRLE
25+
int32_t runlength = -1;
26+
int32_t c_to_dup = -1;
27+
28+
uint32_t lastRefresh = 0;
29+
30+
#define SHARP_SS A5
31+
Adafruit_SharpMem display(&SPI, SHARP_SS, 400, 240, 3000000);
32+
#define X_OFFSET (400 - SCALE*128) / 2
33+
#define Y_OFFSET (240 - SCALE*64) / 2
34+
35+
Adafruit_FlashTransport_QSPI flashTransport;
36+
Adafruit_SPIFlash flash(&flashTransport);
37+
FatFileSystem fatfs;
38+
39+
40+
void putPixels(uint8_t c, int32_t len) {
41+
static uint8_t color;
42+
uint8_t b = 0;
43+
while(len--) {
44+
b = 128;
45+
for (int i=0; i<8; i++) {
46+
if (c & b) {
47+
color = WHITE;
48+
} else {
49+
color = BLACK;
50+
}
51+
b >>= 1;
52+
if (color == BLACK) {
53+
// we clear the buffer each frame so only black pixels need to be drawn
54+
display.fillRect(X_OFFSET+curr_x*SCALE, Y_OFFSET+curr_y*SCALE, SCALE, SCALE, color);
55+
}
56+
curr_x++;
57+
if(curr_x >= 128) {
58+
curr_x = 0;
59+
curr_y++;
60+
if(curr_y >= 64) {
61+
curr_y = 0;
62+
display.refresh();
63+
display.clearDisplayBuffer();
64+
// 30 fps target rate
65+
//if(digitalRead(0)) while((millis() - lastRefresh) < 33) ;
66+
//lastRefresh = millis();
67+
}
68+
}
69+
}
70+
}
71+
}
72+
73+
void decodeRLE(uint8_t c) {
74+
if(c_to_dup == -1) {
75+
if((c == 0x55) || (c == 0xaa)) {
76+
c_to_dup = c;
77+
} else {
78+
putPixels(c, 1);
79+
}
80+
} else {
81+
if(runlength == -1) {
82+
if(c == 0) {
83+
putPixels(c_to_dup & 0xff, 1);
84+
c_to_dup = -1;
85+
} else if((c & 0x80) == 0) {
86+
if(c_to_dup == 0x55) {
87+
putPixels(0, c);
88+
} else {
89+
putPixels(255, c);
90+
}
91+
c_to_dup = -1;
92+
} else {
93+
runlength = c & 0x7f;
94+
}
95+
} else {
96+
runlength = runlength | (c << 7);
97+
if(c_to_dup == 0x55) {
98+
putPixels(0, runlength);
99+
} else {
100+
putPixels(255, runlength);
101+
}
102+
c_to_dup = -1;
103+
runlength = -1;
104+
}
105+
}
106+
}
107+
108+
#define RLEBUFSIZE 4096
109+
#define READBUFSIZE 2048
110+
void readFile(const char * path){
111+
static uint8_t rle_buf[RLEBUFSIZE];
112+
size_t rle_bufhead = 0;
113+
size_t rle_size = 0;
114+
115+
size_t filelen = 0;
116+
size_t filesize;
117+
static uint8_t compbuf[READBUFSIZE];
118+
119+
Serial.printf("Reading file: %s\n", path);
120+
File file = fatfs.open(path);
121+
if(!file || file.isDirectory()){
122+
Serial.println("Failed to open file for reading");
123+
display.println("File open error. Upload video.hs using CircuitPython");
124+
display.refresh();
125+
return;
126+
}
127+
filelen = file.size();
128+
filesize = filelen;
129+
Serial.printf("File size: %d\n", filelen);
130+
131+
// init display, putPixels and decodeRLE
132+
display.clearDisplay();
133+
display.refresh();
134+
curr_x = 0;
135+
curr_y = 0;
136+
runlength = -1;
137+
c_to_dup = -1;
138+
lastRefresh = millis();
139+
140+
// init decoder
141+
heatshrink_decoder_reset(&hsd);
142+
size_t count = 0;
143+
uint32_t sunk = 0;
144+
size_t toRead;
145+
size_t toSink = 0;
146+
uint32_t sinkHead = 0;
147+
148+
149+
// Go through file...
150+
while(filelen) {
151+
if(toSink == 0) {
152+
toRead = filelen;
153+
if(toRead > READBUFSIZE) toRead = READBUFSIZE;
154+
file.read(compbuf, toRead);
155+
filelen -= toRead;
156+
toSink = toRead;
157+
sinkHead = 0;
158+
}
159+
160+
// uncompress buffer
161+
HSD_sink_res sres;
162+
sres = heatshrink_decoder_sink(&hsd, &compbuf[sinkHead], toSink, &count);
163+
//Serial.print("^^ sinked ");
164+
//Serial.println(count);
165+
toSink -= count;
166+
sinkHead = count;
167+
sunk += count;
168+
if (sunk == filesize) {
169+
heatshrink_decoder_finish(&hsd);
170+
}
171+
172+
HSD_poll_res pres;
173+
do {
174+
rle_size = 0;
175+
pres = heatshrink_decoder_poll(&hsd, rle_buf, RLEBUFSIZE, &rle_size);
176+
//Serial.print("^^ polled ");
177+
//Serial.println(rle_size);
178+
if(pres < 0) {
179+
Serial.print("POLL ERR! ");
180+
Serial.println(pres);
181+
return;
182+
}
183+
184+
rle_bufhead = 0;
185+
while(rle_size) {
186+
rle_size--;
187+
if(rle_bufhead >= RLEBUFSIZE) {
188+
Serial.println("RLE_SIZE ERR!");
189+
return;
190+
}
191+
decodeRLE(rle_buf[rle_bufhead++]);
192+
}
193+
} while (pres == HSDR_POLL_MORE);
194+
}
195+
file.close();
196+
Serial.println("Done.");
197+
}
198+
199+
200+
201+
void setup(){
202+
Serial.begin(115200);
203+
//while (!Serial) delay(10);
204+
Serial.println("Bad apple");
205+
206+
flash.begin();
207+
// Init file system on the flash
208+
fatfs.begin(&flash);
209+
210+
display.begin();
211+
display.clearDisplay();
212+
display.setTextColor(BLACK, WHITE);
213+
display.setTextSize(2);
214+
display.println("Scaled Bad Apple For SHARP Memory");
215+
display.refresh();
216+
217+
readFile("/video.hs");
218+
}
219+
220+
void loop(){
221+
222+
}

SHARP_BadApple/data/video.hs

908 KB
Binary file not shown.

SHARP_BadApple/heatshrink_common.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef HEATSHRINK_H
2+
#define HEATSHRINK_H
3+
4+
#define HEATSHRINK_AUTHOR "Scott Vokes <[email protected]>"
5+
#define HEATSHRINK_URL "https://github.com/atomicobject/heatshrink"
6+
7+
/* Version 0.4.1 */
8+
#define HEATSHRINK_VERSION_MAJOR 0
9+
#define HEATSHRINK_VERSION_MINOR 4
10+
#define HEATSHRINK_VERSION_PATCH 1
11+
12+
#define HEATSHRINK_MIN_WINDOW_BITS 4
13+
#define HEATSHRINK_MAX_WINDOW_BITS 15
14+
15+
#define HEATSHRINK_MIN_LOOKAHEAD_BITS 3
16+
17+
#define HEATSHRINK_LITERAL_MARKER 0x01
18+
#define HEATSHRINK_BACKREF_MARKER 0x00
19+
20+
#endif

SHARP_BadApple/heatshrink_config.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef HEATSHRINK_CONFIG_H
2+
#define HEATSHRINK_CONFIG_H
3+
4+
/* Should functionality assuming dynamic allocation be used? */
5+
#ifndef HEATSHRINK_DYNAMIC_ALLOC
6+
#define HEATSHRINK_DYNAMIC_ALLOC 0
7+
#endif
8+
9+
#if HEATSHRINK_DYNAMIC_ALLOC
10+
/* Optional replacement of malloc/free */
11+
#define HEATSHRINK_MALLOC(SZ) malloc(SZ)
12+
#define HEATSHRINK_FREE(P, SZ) free(P)
13+
#else
14+
/* Required parameters for static configuration */
15+
#define HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 2048
16+
#define HEATSHRINK_STATIC_WINDOW_BITS 11
17+
#define HEATSHRINK_STATIC_LOOKAHEAD_BITS 4
18+
#endif
19+
20+
/* Turn on logging for debugging. */
21+
#define HEATSHRINK_DEBUGGING_LOGS 0
22+
23+
/* Use indexing for faster compression. (This requires additional space.) */
24+
#define HEATSHRINK_USE_INDEX 1
25+
26+
#endif

0 commit comments

Comments
 (0)