├── CACHE.HTM
├── LCD.cpp
├── LCD.h
├── LCDfont.h
├── PIP_07.ino
├── README.md
└── tags.h
/CACHE.HTM:
--------------------------------------------------------------------------------
1 | ____ __ ____
2 | / __ \ / / / __ \
3 | / /_/ / / / / /_/ /
4 | / ____/ / / / ____/
5 | / / / / / /
6 | /_/ /_/ /_/
7 |
8 | PIP Micro Web Browser v0.7 (c) Chris Anderson 2014
9 |
--------------------------------------------------------------------------------
/LCD.cpp:
--------------------------------------------------------------------------------
1 | #include "LCD.h"
2 | #include "LCDfont.c"
3 | #include
4 | #include "pins_arduino.h"
5 | #include "wiring_private.h"
6 | //#include
7 | #include
8 |
9 | #define SCLK 13 // Don't change
10 | #define MOSI 11 // Don't change
11 | #define CS 9
12 | #define DC 8
13 | #define RST 7 // you can also connect this to the Arduino reset
14 |
15 | #define DELAY 0x80
16 |
17 | #define TFT_CASET 0x2A
18 | #define TFT_RASET 0x2B
19 | #define TFT_RAMWR 0x2C
20 |
21 | // SPI/TFT setup
22 | volatile uint8_t *csport, *rsport;
23 | uint8_t datapinmask, clkpinmask, cspinmask, rspinmask;
24 |
25 |
26 | //================================================
27 | // LCD object init
28 | //================================================
29 | LCD::LCD (int16_t w, int16_t h):
30 | WIDTH(w), HEIGHT(h), CURSOR_WIDTH(w / TEXTWIDTH), CURSOR_HEIGHT (h / TEXTHEIGHT) {
31 | cursorX = 0;
32 | cursorY = 0;
33 | textColour = 0xFFFF;
34 | bgColour = 0x0000;
35 | wrap = true;
36 | }
37 |
38 | //================================================
39 | // SPI write commands
40 | //================================================
41 | void spiwrite (uint8_t c) {
42 | SPDR = c;
43 | while (!(SPSR & _BV(SPIF)));
44 | }
45 |
46 | void writecommand (uint8_t c) {
47 | *rsport &= ~rspinmask;
48 | *csport &= ~cspinmask;
49 | spiwrite (c);
50 | *csport |= cspinmask;
51 | }
52 |
53 | void writedata (uint8_t c) {
54 | *rsport |= rspinmask;
55 | *csport &= ~cspinmask;
56 | spiwrite (c);
57 | *csport |= cspinmask;
58 | }
59 |
60 | void setAddrWindow (uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
61 | writecommand (TFT_CASET); // Column addr set
62 | writedata (y0 >> 8);
63 | writedata (y0 & 0xff); // YSTART
64 | writedata (y1 >> 8);
65 | writedata (y1 & 0xff); // YEND
66 | writecommand (TFT_RASET); // Row addr set
67 | writedata (x0 >> 8);
68 | writedata (x0 & 0xff); // XSTART
69 | writedata (x1 >> 8);
70 | writedata (x1 & 0xff); // XEND
71 | writecommand (TFT_RAMWR); // write to RAM
72 | }
73 |
74 |
75 | //================================================
76 | // LCD init code store
77 | //================================================
78 | static const uint8_t PROGMEM LCDinit[] = {
79 | 21,
80 | 0xcb, 5, 0x39, 0x2c, 0x00, 0x34, 0x02,
81 | 0xcf, 3, 0x00, 0xc1, 0x30,
82 | 0xe8, 3, 0x85, 0x00, 0x78,
83 | 0xea, 2, 0x00, 0x00,
84 | 0xed, 4, 0x64, 0x03, 0x12, 0x81,
85 | 0xf7, 1, 0x20,
86 | 0xc0, 1, 0x23,
87 | 0xc1, 1, 0x10,
88 | 0xc5, 2, 0x3e, 0x28,
89 | 0xc7, 1, 0x86,
90 | 0x36, 1, 0x08,
91 | 0x3a, 1, 0x55,
92 | 0xb1, 2, 0x00, 0x18,
93 | 0xb6, 3, 0x08, 0x82, 0x27,
94 | 0xf2, 1, 0x00,
95 | 0x26, 1, 0x01,
96 | 0xe0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00,
97 | 0xe1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x031, 0xc1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f,
98 | 0x11, 0+DELAY, 120,
99 | 0x29, 0,
100 | 0x2c, 0
101 | };
102 | //0x08,
103 |
104 | //================================================
105 | // LCD init code handler
106 | //================================================
107 | void commandList (const uint8_t *addr) {
108 | uint8_t numCommands, numArgs;
109 | uint16_t ms;
110 |
111 | numCommands = pgm_read_byte (addr++); // Number of commands to follow
112 |
113 | while (numCommands--) { // For each command...
114 | writecommand (pgm_read_byte (addr++)); // Read, issue command
115 | numArgs = pgm_read_byte (addr++); // Number of args to follow
116 | ms = numArgs & DELAY; // If hibit set, delay follows args
117 | numArgs &= ~DELAY; // Mask out delay bit
118 | while (numArgs--) { // For each argument...
119 | writedata (pgm_read_byte (addr++)); // Read, issue argument
120 | }
121 | if (ms) {
122 | ms = pgm_read_byte (addr++); // Read post-command delay time (ms)
123 | if (ms == 255) ms = 500; // If 255, delay for 500 ms
124 | delay (ms);
125 | }
126 | }
127 | }
128 |
129 |
130 | //================================================
131 | // Init LCD object and LCD panel
132 | //================================================
133 | void LCD::init() {
134 | pinMode (DC, OUTPUT);
135 | pinMode (CS, OUTPUT);
136 | pinMode (RST, OUTPUT);
137 | csport = portOutputRegister(digitalPinToPort(CS));
138 | rsport = portOutputRegister(digitalPinToPort(DC));
139 | cspinmask = digitalPinToBitMask(CS);
140 | rspinmask = digitalPinToBitMask(DC);
141 |
142 | SPI.begin();
143 | //SPI.setClockDivider (SPI_CLOCK_DIV4); // 4 MHz (half speed)
144 | //Due defaults to 4mHz (clock divider setting of 21)
145 | SPI.setBitOrder (MSBFIRST);
146 | SPI.setDataMode (SPI_MODE0);
147 |
148 | // toggle RST low to reset; CS low so it'll listen to us
149 | *csport &= ~cspinmask;
150 | digitalWrite (RST, HIGH);
151 | delay (10);
152 | digitalWrite (RST, LOW);
153 | delay (10);
154 | digitalWrite (RST, HIGH);
155 | delay (10);
156 |
157 | commandList (LCDinit);
158 | digitalWrite (CS, HIGH);
159 |
160 | fillRect (0 ,0, WIDTH, HEIGHT, BLACK);
161 | }
162 |
163 |
164 | //================================================
165 | // LCD write
166 | //================================================
167 | size_t LCD::write (uint8_t c) {
168 | if (c == '\n') {
169 | // fillRect (cursorX, cursorY, WIDTH - cursorX, TEXTHEIGHT, bgColour); // Blank rest of line
170 | cursorX = 0;
171 | cursorY += TEXTHEIGHT;
172 | if (cursorY == CURSOR_HEIGHT) return 1;
173 | }
174 | else if (c != '\r') { // Skip '\r'
175 | drawChar(cursorX, cursorY, c, textColour, bgColour);
176 | cursorX += TEXTWIDTH;
177 | if (wrap && (cursorX > (WIDTH - TEXTWIDTH))) {
178 | cursorX = 0;
179 | cursorY += TEXTHEIGHT;
180 | if (cursorY > HEIGHT) cursorY = 1;
181 | }
182 | }
183 | return 1;
184 | }
185 |
186 | //================================================
187 | // LCD draw character
188 | //================================================
189 | void LCD::drawChar (int16_t x, int16_t y, unsigned char c, uint16_t colour, uint16_t bg) {
190 | unsigned char charData;
191 |
192 | if((x >= WIDTH) || (y >= HEIGHT) || ((x + TEXTWIDTH - 1) < 0) || ((y + TEXTHEIGHT - 1) < 0))
193 | return;
194 |
195 | c -= 32; // Shift ASCII to font array values
196 | if ((c < 0) || (c > 97)) c = 97;
197 |
198 | uint8_t fhi = colour >> 8, flo = colour & 0xff;
199 | uint8_t bhi = bg >> 8, blo = bg & 0xff;
200 |
201 | setAddrWindow (x, y, x + TEXTWIDTH - 1, y + TEXTHEIGHT - 1);
202 |
203 | *rsport |= rspinmask;
204 | *csport &= ~cspinmask;
205 |
206 | for (int8_t i = 0; i < TEXTWIDTH; i++ ) {
207 | charData = pgm_read_byte (font + (c * (TEXTWIDTH - 1)) + i);
208 |
209 | for (int8_t j = 0; j < TEXTHEIGHT; j++) {
210 |
211 | if ((i < (TEXTWIDTH -1)) && ((charData >> j) & 0x01)) {
212 | spiwrite (fhi);
213 | spiwrite (flo);
214 | }
215 | else {
216 | spiwrite (bhi);
217 | spiwrite (blo);
218 | }
219 |
220 | }
221 | }
222 |
223 | *csport |= cspinmask;
224 |
225 | }
226 |
227 |
228 | //================================================
229 | // Filled rectangle
230 | //================================================
231 | void LCD::fillRect (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colour) {
232 |
233 | if ((x >= WIDTH) || (y >= HEIGHT)) return;
234 | if ((x + --w) >= WIDTH) w = WIDTH - x - 1;
235 | if ((y + --h) >= WIDTH) h = WIDTH - y - 1;
236 |
237 | setAddrWindow (x, y, x + w, y + h);
238 |
239 | uint8_t hi = colour >> 8;
240 | uint8_t lo = colour & 0xff;
241 | *rsport |= rspinmask;
242 | *csport &= ~cspinmask;
243 |
244 | for (y = h; y >= 0; y--) {
245 | for (x = w; x >= 0; x--) {
246 | spiwrite (hi);
247 | spiwrite (lo);
248 | }
249 | }
250 | *csport |= cspinmask;
251 | }
252 |
253 |
254 | //================================================
255 | // Utility functions
256 | //================================================
257 | void LCD::setCursor (int16_t x, int16_t y) {
258 | cursorX = x * TEXTWIDTH;
259 | cursorY = y * TEXTHEIGHT;
260 | }
261 |
262 | void LCD::setTextColour (uint16_t c) {
263 | textColour = c;
264 | }
265 |
266 | void LCD::setBGColour (uint16_t b) {
267 | bgColour = b;
268 | }
269 |
270 | int16_t LCD::getTextColour () {
271 | return textColour;
272 | }
273 |
274 | int16_t LCD::getBGColour () {
275 | return bgColour;
276 | }
277 |
278 | void LCD::setTextWrap (boolean w) {
279 | wrap = w;
280 | }
281 |
282 | int16_t LCD::getCursorX() {
283 | return cursorX;
284 | }
285 |
286 | int16_t LCD::getCursorY() {
287 | return cursorY;
288 | }
289 |
--------------------------------------------------------------------------------
/LCD.h:
--------------------------------------------------------------------------------
1 | #ifndef _LCD_H
2 | #define _LCD_H
3 |
4 | #include "Arduino.h"
5 | #include "Print.h"
6 |
7 | #define BLACK 0x0000
8 | #define RED 0xF800
9 | #define GREEN 0x07E0
10 | #define BLUE 0x001F
11 | #define YELLOW 0xFFE0
12 | #define MAGENTA 0xF81F
13 | #define CYAN 0x07FF
14 | #define WHITE 0xFFFF
15 | #define GREY 0x632C
16 |
17 | #define TEXTWIDTH 6
18 | #define TEXTHEIGHT 8
19 |
20 | class LCD :
21 | public Print {
22 |
23 | public:
24 | LCD(int16_t w, int16_t h);
25 |
26 | void init();
27 |
28 | void fillRect (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colour);
29 | void drawChar (int16_t x, int16_t y, unsigned char c, uint16_t colour, uint16_t bg);
30 |
31 | virtual size_t write (uint8_t);
32 |
33 | void setCursor (int16_t x, int16_t y);
34 | void setTextColour (uint16_t c);
35 | void setBGColour (uint16_t bg);
36 | int16_t getTextColour ();
37 | int16_t getBGColour ();
38 | void setTextWrap (boolean w);
39 | int16_t getCursorX();
40 | int16_t getCursorY();
41 |
42 | const int16_t WIDTH, HEIGHT;
43 | const int16_t CURSOR_WIDTH, CURSOR_HEIGHT;
44 |
45 | protected:
46 | int16_t cursorX, cursorY;
47 | uint16_t textColour, bgColour;
48 | boolean wrap; // If set, 'wrap' text at right edge of display
49 | };
50 |
51 | #endif // _LCD_H
52 |
--------------------------------------------------------------------------------
/LCDfont.h:
--------------------------------------------------------------------------------
1 | #ifndef _FONT_C
2 | #define _FONT_C
3 |
4 | // #include
5 | #include
6 |
7 | // Standard ASCII 5x7 font for chars 32+
8 | static const char font[] PROGMEM = {
9 | 0x00, 0x00, 0x00, 0x00, 0x00, // Space
10 | 0x00, 0x00, 0x5F, 0x00, 0x00, // !
11 | 0x00, 0x07, 0x00, 0x07, 0x00, // "
12 | 0x14, 0x7F, 0x14, 0x7F, 0x14,
13 | 0x24, 0x2A, 0x7F, 0x2A, 0x12,
14 | 0x23, 0x13, 0x08, 0x64, 0x62,
15 | 0x36, 0x49, 0x56, 0x20, 0x50,
16 | 0x00, 0x08, 0x07, 0x03, 0x00,
17 | 0x00, 0x1C, 0x22, 0x41, 0x00,
18 | 0x00, 0x41, 0x22, 0x1C, 0x00,
19 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
20 | 0x08, 0x08, 0x3E, 0x08, 0x08,
21 | 0x00, 0x80, 0x70, 0x30, 0x00,
22 | 0x08, 0x08, 0x08, 0x08, 0x08,
23 | 0x00, 0x00, 0x60, 0x60, 0x00,
24 | 0x20, 0x10, 0x08, 0x04, 0x02,
25 | 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
26 | 0x00, 0x42, 0x7F, 0x40, 0x00,
27 | 0x72, 0x49, 0x49, 0x49, 0x46,
28 | 0x21, 0x41, 0x49, 0x4D, 0x33,
29 | 0x18, 0x14, 0x12, 0x7F, 0x10,
30 | 0x27, 0x45, 0x45, 0x45, 0x39,
31 | 0x3C, 0x4A, 0x49, 0x49, 0x31,
32 | 0x41, 0x21, 0x11, 0x09, 0x07,
33 | 0x36, 0x49, 0x49, 0x49, 0x36,
34 | 0x46, 0x49, 0x49, 0x29, 0x1E, // 9
35 | 0x00, 0x00, 0x14, 0x00, 0x00,
36 | 0x00, 0x40, 0x34, 0x00, 0x00,
37 | 0x00, 0x08, 0x14, 0x22, 0x41,
38 | 0x14, 0x14, 0x14, 0x14, 0x14,
39 | 0x00, 0x41, 0x22, 0x14, 0x08,
40 | 0x02, 0x01, 0x59, 0x09, 0x06,
41 | 0x3E, 0x41, 0x5D, 0x59, 0x4E,
42 | 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
43 | 0x7F, 0x49, 0x49, 0x49, 0x36,
44 | 0x3E, 0x41, 0x41, 0x41, 0x22,
45 | 0x7F, 0x41, 0x41, 0x41, 0x3E,
46 | 0x7F, 0x49, 0x49, 0x49, 0x41,
47 | 0x7F, 0x09, 0x09, 0x09, 0x01,
48 | 0x3E, 0x41, 0x41, 0x51, 0x73,
49 | 0x7F, 0x08, 0x08, 0x08, 0x7F,
50 | 0x00, 0x41, 0x7F, 0x41, 0x00,
51 | 0x20, 0x40, 0x41, 0x3F, 0x01,
52 | 0x7F, 0x08, 0x14, 0x22, 0x41,
53 | 0x7F, 0x40, 0x40, 0x40, 0x40,
54 | 0x7F, 0x02, 0x1C, 0x02, 0x7F,
55 | 0x7F, 0x04, 0x08, 0x10, 0x7F,
56 | 0x3E, 0x41, 0x41, 0x41, 0x3E,
57 | 0x7F, 0x09, 0x09, 0x09, 0x06,
58 | 0x3E, 0x41, 0x51, 0x21, 0x5E,
59 | 0x7F, 0x09, 0x19, 0x29, 0x46,
60 | 0x26, 0x49, 0x49, 0x49, 0x32,
61 | 0x03, 0x01, 0x7F, 0x01, 0x03,
62 | 0x3F, 0x40, 0x40, 0x40, 0x3F,
63 | 0x1F, 0x20, 0x40, 0x20, 0x1F,
64 | 0x3F, 0x40, 0x38, 0x40, 0x3F,
65 | 0x63, 0x14, 0x08, 0x14, 0x63,
66 | 0x03, 0x04, 0x78, 0x04, 0x03,
67 | 0x61, 0x59, 0x49, 0x4D, 0x43, // Z
68 | 0x00, 0x7F, 0x41, 0x41, 0x41,
69 | 0x02, 0x04, 0x08, 0x10, 0x20,
70 | 0x00, 0x41, 0x41, 0x41, 0x7F,
71 | 0x04, 0x02, 0x01, 0x02, 0x04,
72 | 0x40, 0x40, 0x40, 0x40, 0x40,
73 | 0x00, 0x03, 0x07, 0x08, 0x00,
74 | 0x20, 0x54, 0x54, 0x78, 0x40, // a
75 | 0x7F, 0x28, 0x44, 0x44, 0x38,
76 | 0x38, 0x44, 0x44, 0x44, 0x28,
77 | 0x38, 0x44, 0x44, 0x28, 0x7F,
78 | 0x38, 0x54, 0x54, 0x54, 0x18,
79 | 0x00, 0x08, 0x7E, 0x09, 0x02,
80 | 0x18, 0xA4, 0xA4, 0x9C, 0x78,
81 | 0x7F, 0x08, 0x04, 0x04, 0x78,
82 | 0x00, 0x44, 0x7D, 0x40, 0x00,
83 | 0x20, 0x40, 0x40, 0x3D, 0x00,
84 | 0x7F, 0x10, 0x28, 0x44, 0x00,
85 | 0x00, 0x41, 0x7F, 0x40, 0x00,
86 | 0x7C, 0x04, 0x78, 0x04, 0x78,
87 | 0x7C, 0x08, 0x04, 0x04, 0x78,
88 | 0x38, 0x44, 0x44, 0x44, 0x38,
89 | 0xFC, 0x18, 0x24, 0x24, 0x18,
90 | 0x18, 0x24, 0x24, 0x18, 0xFC,
91 | 0x7C, 0x08, 0x04, 0x04, 0x08,
92 | 0x48, 0x54, 0x54, 0x54, 0x24,
93 | 0x04, 0x04, 0x3F, 0x44, 0x24,
94 | 0x3C, 0x40, 0x40, 0x20, 0x7C,
95 | 0x1C, 0x20, 0x40, 0x20, 0x1C,
96 | 0x3C, 0x40, 0x30, 0x40, 0x3C,
97 | 0x44, 0x28, 0x10, 0x28, 0x44,
98 | 0x4C, 0x90, 0x90, 0x90, 0x7C, // y
99 | 0x44, 0x64, 0x54, 0x4C, 0x44, // z
100 | 0x00, 0x08, 0x36, 0x41, 0x00, // {
101 | 0x00, 0x00, 0x7f, 0x00, 0x00, // |
102 | 0x00, 0x41, 0x36, 0x08, 0x00, // }
103 | 0x02, 0x01, 0x02, 0x04, 0x02, // ~ 126
104 | 0x18, 0x3c ,0x18, 0x00, 0x00, // Bullet point (not ASCII) 127
105 | 0x00, 0x00 ,0x00, 0x00, 0x00, // 128
106 | 0x00, 0x7F, 0x41, 0x41, 0x7F // Unprintable characters 129
107 | };
108 | #endif // _FONT_C
109 |
--------------------------------------------------------------------------------
/PIP_07.ino:
--------------------------------------------------------------------------------
1 | /*================================================
2 | =================================================
3 | #### ### ####
4 | # # # # #
5 | # # # # #
6 | #### # ####
7 | # # #
8 | # # #
9 | # ### #
10 |
11 | PIP Micro Web Browser v0.7
12 | Suitable for 32KB Arduino/ATmega use.
13 |
14 | (c) Chris Anderson 2014.
15 |
16 | Creative Commons license:
17 | Creative Commons Attribution 4.0 International License
18 | http://creativecommons.org/licenses/by/4.0/
19 |
20 | PIP is a functional but incomplete web browser for Arduino and runs
21 | well on an Uno. It can download and render plain HTML (no images, CSS
22 | or Javascript) and follow embedded links. It's joystick controlled
23 | and uses a 320x240 LCD screen for output.
24 |
25 | The Ethernet and SD card libraries use about 20KB of code, so the LCD
26 | driver, HTML parser and renderer squeeze in under 12KB.
27 |
28 | Requires:
29 |
30 | * Arduino Uno or similiar ATmega 328 powered board
31 | * Wiz5100 powered Ethernet board with SD card slot (SPI CS = 10 & 4)
32 | * 320x240 TFT LCD screen (SPI CS = 9) Found here: http://tinyurl.com/tftlcd
33 | * Analogue joystick with button (PS2 style)
34 |
35 | Installation:
36 |
37 | * Plug an SD card (MAXIMUM 2GB) into your computer and copy the file
38 | "CACHE.HTM" from this enclosing folder into the root level of the card.
39 | * Download the file "HOME.HTM" from the URL below and put it in the enclosing
40 | folder. Then copy the file to the root level of the SD card.
41 | https://www.dropbox.com/s/v8h2d94uxxcw1oj/HOME.HTM?dl=0
42 | * Put the SD card into your Ethernet shield and upload PIP to your Arduino.
43 | * Rename the enclosing folder of this file to "PIP_07.ino".
44 | * Copy the enclosing folder into you local Arduino sketch folder, as per
45 | usual for new programs.
46 |
47 | Wiring for LCD:
48 | Name Pin
49 | SCLK 13 Clock
50 | MOSI 11 Master Out - Don't change or you loose hardware assisted speed
51 | CS 9 Chip Select
52 | DC 8 Data/Comand
53 | RST 7 Reset
54 | LED Arduino 3.3v
55 | VCC Arduino 5v
56 | GND Ground
57 |
58 | Wiring for joystick:
59 | VRx A0 - Analogue input 0
60 | VRy A1
61 | SW A2
62 | VCC Arduino 5v
63 | GND Ground
64 |
65 | Notes:
66 |
67 | Handles a sub-set of HTML tags. See tags.h file for list.
68 |
69 | HTML pages over 20KB or so can stall and fail somewhat randomly. The Wiz5100
70 | just doesn't seem to like dripping data to an Arduino much. Over 1KB/sec
71 | download speed can be cosidered 'good'.
72 |
73 | Occationally when the browser crashes during a render, the HOME.HTM can get
74 | corrupted. Just copy the file in the enclosing folder back onto the SD card.
75 |
76 | Due to poor Ethernet and SD card interaction on the SPI bus, the cace file
77 | on the SD card is held open as long as possible and only closed and re-opened
78 | during HTML download and parsing. That seems to make things ore reliable.
79 |
80 | HTML files are parsed and made partially binary before being stored on the CD card.
81 | File are generally around 50% smaller when unused junk is removed. The stored
82 | file will be truncated to 64KB as 16 bit pointers are being used for page and
83 | URL indexing.
84 | May fix this by going to relative pointers.
85 |
86 | Currently, URLs over 90 characters in size are truncated. This will undoubtably
87 | break them, or results in 404 errors. Which aren't handled well yet.
88 |
89 | The LCD screen is used via a custom library (very similar to the Adafruit GFX
90 | library) which only implements rectangle and character drawing to save space.
91 | As only rectangle drawing and the print command are used, it should be easy to
92 | adapt PIP to use a different LCD.
93 |
94 | Doesn't do images. Come on, there's only 2KB of memory and a tiny screen
95 | to play with! JPEG parsing might be problematic as there's only 2KB of
96 | program space free.
97 |
98 | Forms are not even attempted. There's no keyboard, so good luck with that.
99 |
100 | To do:
101 | Handle state case when a page break the middle of a tag.
102 |
103 | v0.7 14/10/2014
104 | Fixed exception for
17 | #define PIP 546 // custom tag
18 |
19 | // Use non-printable ASCII characters for tag codes
20 | #define TAG_CR 14 // ~
21 | #define TAG_HEADING1 15 // [
22 | #define TAG_HEADING2 16 // ]
23 | #define TAG_BOLD1 17 // (
24 | #define TAG_BOLD2 18 // )
25 | #define TAG_LINK1 19 // {
28 | #define TAG_HR 22 // %
29 | #define TAG_LIST 23 // *
30 | #define TAG_PRE 24 // `
31 | #define TAG_PRE2 25 // '
32 | #define TAG_HTTP 26 // http://
33 |
34 | /*
35 | #define TAG_CR 182 //¶ 14 // ~
36 | #define TAG_HEADING1 167 //§ 15 // [
37 | #define TAG_HEADING2 168 //¨ 16 // ]
38 | #define TAG_BOLD1 185 //¹ 17 // (
39 | #define TAG_BOLD2 186 //º 18 // )
40 | #define TAG_LINK1 188 //¼ 19 // {
43 | #define TAG_HR 172 //¬ 22 // %
44 | #define TAG_LIST 164 //¤ 23 // *
45 | #define TAG_PRE 162 //¢ 24 // `
46 | #define TAG_PRE2 163 //£ 25 // '
47 | #define TAG_HTTP 187 //» 26 // http://
48 | */
49 |
50 | // Hash flags and masks
51 | #define INLINE 0x8000 // High bit flag for tag allowing post spaces
52 | #define PRE_BREAK 0x4000 // High bit flag for pre-tag render break
53 | #define POST_BREAK 0x2000 // High bit flag for post tag break
54 | #define ATTR_MASK 0x1fff // Mask to remove high bit flags
55 |
56 | // Hash -> tag & flag mappings
57 | #define NUMTAGS 76
58 | static const uint16_t tag_codes[] PROGMEM = {
59 | 161, TAG_HEADING1 | PRE_BREAK, //
60 | 162, TAG_HEADING1 | PRE_BREAK, //
61 | 163, TAG_HEADING1 | PRE_BREAK, //
62 | 164, TAG_HEADING1 | PRE_BREAK, //
63 | 80, TAG_CR | PRE_BREAK, //
64 | 226, TAG_HR | PRE_BREAK | POST_BREAK, //
65 | 246, TAG_CR | PRE_BREAK, //
66 | 234, TAG_CR | PRE_BREAK, //
67 | 225, TAG_LIST | PRE_BREAK, // -
68 | PRETAG, TAG_PRE | PRE_BREAK, //
69 |
70 | 221, TAG_HEADING2 | POST_BREAK, //
71 | 222, TAG_HEADING2 | POST_BREAK, //
72 | 223, TAG_HEADING2 | POST_BREAK, //
73 | 224, TAG_HEADING2 | POST_BREAK, //
74 |
75 | 443, TAG_CR | POST_BREAK, //
76 | 214, TAG_CR | POST_BREAK, //
77 | 110, TAG_CR | POST_BREAK, //
78 | 294, TAG_CR | POST_BREAK, //
79 | 306, TAG_CR | POST_BREAK, //
80 | 285, TAG_CR | POST_BREAK, //
81 | PRETAGEND, TAG_PRE2 | POST_BREAK, //
82 |
83 | 66, TAG_BOLD1 | INLINE, //
84 | 96, TAG_BOLD2 | INLINE, //
85 | 5199, TAG_BOLD1 | INLINE, //
86 | 6159, TAG_BOLD2 | INLINE, //
87 | 65, TAG_LINK1 | INLINE, //
88 | HREFTAG, TAG_LINK2 | INLINE, // URL
89 | 95, TAG_LINK3 | INLINE, //
90 |
91 | 1428, 38, // Ampersand
92 | 2682, 96, // 8216; Curly single quote
93 | 2683, 39, // 8217; Curly single quote
94 | 6460, 128, // nbsp;
95 | 2680, 34, // 8220; Curly double quotes
96 | 2681, 34, // 8221; Curly double quotes
97 | 2677, 45, // 8211; Hyphens en
98 | 2678, 45, // 8212; Hyphens em
99 | 368, 62, // Greater than
100 | 388, 60 // Less than
101 | };
102 |
--------------------------------------------------------------------------------