Skip to content

Commit d7258f8

Browse files
committed
Added hacky faster Sharp LCD demo for RPI
1 parent fcc9ae1 commit d7258f8

7 files changed

Lines changed: 30420 additions & 3 deletions

File tree

linux/sharp_fast_gif/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CFLAGS=-c -Wall -O3 -D__LINUX__ -D_LINUX_ -DSPI_BUS_NUMBER=0
2+
LIBS = -lpthread -larmbianio
3+
all: gifplay
4+
5+
gifplay: main.o
6+
$(CC) main.o $(LIBS) -o gifplay
7+
8+
main.o: main.c ../../src/obd.inl ../../src/OneBitDisplay.h
9+
$(CC) $(CFLAGS) main.c
10+
11+
clean:
12+
rm -rf *.o gifplay

linux/sharp_fast_gif/main.c

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
//
2+
// main.c
3+
// OneBitDisplay library test program
4+
//
5+
6+
#include <stdio.h>
7+
#include <string.h>
8+
#include <stdlib.h>
9+
#include <stdint.h>
10+
11+
#include <unistd.h>
12+
#include <fcntl.h>
13+
#include <sys/ioctl.h>
14+
#include <math.h>
15+
#include <armbianio.h>
16+
#include <signal.h>
17+
18+
#include "../../../AnimatedGIF/src/AnimatedGIF.h"
19+
#include "../../../AnimatedGIF/src/gif.inl"
20+
#include "../../src/OneBitDisplay.cpp"
21+
#include "pattern_400x240.h"
22+
23+
#define DISPLAY_TYPE SHARP_400x240
24+
#define FLIP180 0
25+
#define INVERT 0
26+
#define DC_PIN -1
27+
#define CS_PIN 16
28+
#define DISP_PIN 18
29+
#define EXTCOM_PIN 22
30+
#define RESET_PIN -1
31+
#define SPEED 8000000
32+
#define BITBANG 0
33+
#define LED_PIN -1
34+
35+
// This is not controlled on Linux through the API
36+
// On the Raspberry PI, see /boot/config.txt
37+
#define DISPLAY_WIDTH 400
38+
#define DISPLAY_HEIGHT 240
39+
#define DISPLAY_PITCH ((DISPLAY_WIDTH>>3)+2)
40+
static uint8_t ucBuffer[(DISPLAY_PITCH * DISPLAY_HEIGHT)+2];
41+
static OBDISP obd;
42+
volatile int iStop = 0;
43+
44+
void my_handler(int signal)
45+
{
46+
iStop = 1;
47+
} /* my_handler() */
48+
49+
//
50+
// This doesn't have to be super efficient
51+
//
52+
void DrawPixel(int x, int y, uint8_t ucColor)
53+
{
54+
uint8_t *d, ucMask;
55+
56+
ucMask = 0x80 >> (x & 7);
57+
d = &ucBuffer[2 + (x>>3) + (y*DISPLAY_PITCH)];
58+
if (ucColor)
59+
*d &= ~ucMask;
60+
else
61+
*d |= ucMask;
62+
}
63+
64+
// Draw a line of image into our 1-bpp virtual display buffers
65+
void GIFDraw(GIFDRAW *pDraw)
66+
{
67+
uint8_t *s, *d = &ucBuffer[2];
68+
int x, y, iWidth;
69+
int iX = pDraw->iX;
70+
static uint8_t ucPalette[256]; // thresholded palette
71+
72+
if (pDraw->y == 0) // first line, convert palette to 0/1
73+
{
74+
for (x = 0; x < 256; x++)
75+
{
76+
uint16_t usColor = pDraw->pPalette[x];
77+
int gray = (usColor & 0xf800) >> 8; // red
78+
gray += ((usColor & 0x7e0) >> 2); // plus green*2
79+
gray += ((usColor & 0x1f) << 3); // plus blue
80+
ucPalette[x] = (gray >> 9); // 0->511 = 0, 512->1023 = 1
81+
}
82+
}
83+
y = pDraw->iY + pDraw->y; // current line
84+
d += (y * DISPLAY_PITCH);
85+
iWidth = pDraw->iWidth;
86+
if (iWidth > DISPLAY_WIDTH)
87+
iWidth = DISPLAY_WIDTH;
88+
89+
s = pDraw->pPixels;
90+
if (pDraw->ucDisposalMethod == 2) // restore to background color
91+
{
92+
for (x=0; x<iWidth; x++)
93+
{
94+
if (s[x] == pDraw->ucTransparent)
95+
s[x] = pDraw->ucBackground;
96+
}
97+
pDraw->ucHasTransparency = 0;
98+
}
99+
// Apply the new pixels to the main image
100+
if (pDraw->ucHasTransparency) // if transparency used
101+
{
102+
uint8_t c, ucTransparent = pDraw->ucTransparent;
103+
int x;
104+
for(x=0; x < iWidth; x++)
105+
{
106+
c = *s++;
107+
if (c != ucTransparent) {
108+
// DrawPixel(iX + x, y, ucPalette[c]);
109+
if (ucPalette[c]) d[((iX+x)>>3)] |= (0x80 >> ((iX+x)&7));
110+
else d[((iX+x)>>3)] &= ~(0x80 >> ((iX+x)&7));
111+
}
112+
}
113+
}
114+
else
115+
{
116+
s = pDraw->pPixels;
117+
// Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
118+
for (x=0; x<pDraw->iWidth; x++) {
119+
if (ucPalette[*s++]) d[((iX+x)>>3)] |= (0x80 >> ((iX+x)&7));
120+
else d[((iX+x)>>3)] &= ~(0x80 >> ((iX+x)&7));
121+
//DrawPixel(pDraw->iX + x, y, ucPalette[*s++]);
122+
}
123+
}
124+
if (pDraw->y == pDraw->iHeight-1) { // last line, render it to the display
125+
// obdDumpBuffer(&obd, NULL);
126+
AIOWriteGPIO(CS_PIN, HIGH);
127+
ucBuffer[0] ^= 0x40; // toggle VCOM bit
128+
AIOWriteSPI(obd.bbi2c.file_i2c, ucBuffer, sizeof(ucBuffer));
129+
// RawWriteData(&obd, ucBuffer, sizeof(ucBuffer));
130+
AIOWriteGPIO(CS_PIN, LOW);
131+
}
132+
} /* GIFDraw() */
133+
134+
// Less efficient than a lookup table, but it's only used at init time
135+
// This saves a couple hundred bytes of FLASH
136+
uint8_t MirrorBits(uint8_t v)
137+
{
138+
uint8_t r = v & 1;
139+
uint8_t s = 7;
140+
for (v >>= 1; v; v >>= 1) {
141+
r <<= 1;
142+
r |= (v & 1);
143+
s--;
144+
}
145+
r <<= s; // adjust for 0's
146+
return r;
147+
} /* MirrorBits() */
148+
149+
void PrepBuffer(void)
150+
{
151+
uint8_t *d;
152+
int i;
153+
154+
d = ucBuffer;
155+
*d++ = 0x80; // start byte
156+
for (i=0; i<DISPLAY_HEIGHT; i++) {
157+
d[0] = MirrorBits(i+1); // line number
158+
d[DISPLAY_PITCH-1] = 0; // end byte for this line
159+
d += DISPLAY_PITCH;
160+
}
161+
ucBuffer[(DISPLAY_HEIGHT*DISPLAY_PITCH)+1] = 0; // double 0 to terminate the multi-line mode
162+
} /* PrepBuffer() */
163+
164+
int main(int argc, const char * argv[])
165+
{
166+
GIFIMAGE gif;
167+
int rc;
168+
int iDelay;
169+
struct sigaction sigIntHandler;
170+
171+
// Set CTRL-C signal handler
172+
sigIntHandler.sa_handler = my_handler;
173+
sigemptyset(&sigIntHandler.sa_mask);
174+
sigIntHandler.sa_flags = 0;
175+
sigaction(SIGINT, &sigIntHandler, NULL);
176+
177+
printf("Sharp Memory LCD GIF demo\n");
178+
printf("Press Ctrl-C to quit\n");
179+
180+
rc = AIOInitBoard("Raspberry Pi");
181+
if (rc == 0) // problem
182+
{
183+
printf("Error in AIOInit(); check if this board is supported\n");
184+
return 0;
185+
}
186+
AIOAddGPIO(DISP_PIN, OUTPUT); // enable display
187+
AIOWriteGPIO(DISP_PIN, HIGH);
188+
AIOAddGPIO(EXTCOM_PIN, OUTPUT);
189+
190+
obdSPIInit(&obd, DISPLAY_TYPE, DC_PIN, CS_PIN, RESET_PIN, -1, -1, LED_PIN, FLIP180, INVERT, BITBANG, SPEED);
191+
obdSetBackBuffer(&obd, ucBuffer);
192+
obdFill(&obd, 0, 0);
193+
obdDumpBuffer(&obd, NULL);
194+
PrepBuffer(); // prepare memory for a single SPI write of all lines
195+
GIF_begin(&gif, GIF_PALETTE_RGB565_LE);
196+
while (!iStop) {
197+
rc = GIF_openRAM(&gif, (uint8_t *)pattern_400x240, sizeof(pattern_400x240), GIFDraw);
198+
if (rc) {
199+
while (GIF_playFrame(&gif, &iDelay, NULL)) {
200+
//usleep(iDelay * 1000);
201+
}
202+
} else {
203+
printf("GIF decode error = %d\n", gif.iError);
204+
iStop = 1;
205+
}
206+
} // while (1)
207+
AIOWriteGPIO(DISP_PIN, LOW); // turn off LCD
208+
AIOShutdown();
209+
210+
return 0;
211+
} /* main() */

0 commit comments

Comments
 (0)