summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/lcd.c356
1 files changed, 320 insertions, 36 deletions
diff --git a/firmware/lcd.c b/firmware/lcd.c
index 5563bbe881..e8716a95fc 100644
--- a/firmware/lcd.c
+++ b/firmware/lcd.c
@@ -20,26 +20,41 @@
20#include "lcd.h" 20#include "lcd.h"
21 21
22void lcd_data (int data) 22void lcd_data (int data)
23 { lcd_byte (data,1); } 23{
24 lcd_byte (data,1);
25}
24 26
25void lcd_instruction (int instruction) 27void lcd_instruction (int instruction)
26 { lcd_byte (instruction,0); } 28{
29 lcd_byte (instruction,0);
30}
27 31
28void lcd_zero (int length) 32void lcd_zero (int length)
29 { length *= 8; while (--length >= 0) lcd_data (0); } 33{
34 length *= 8;
35 while (--length >= 0)
36 lcd_data (0);
37}
30 38
31void lcd_fill (int data,int length) 39void lcd_fill (int data,int length)
32 { length *= 8; while (--length >= 0) lcd_data (data); } 40{
41 length *= 8;
42 while (--length >= 0)
43 lcd_data (data);
44}
33 45
34void lcd_copy (void *data,int count) 46void lcd_copy (void *data,int count)
35 { while (--count >= 0) lcd_data (*((char *)data)++); } 47{
48 while (--count >= 0)
49 lcd_data (*((char *)data)++);
50}
36 51
37 52
38#ifdef JBP 53#ifdef HAVE_LCD_CHARCELLS
39# ifndef JBP_OLD 54# ifndef JBP_OLD
40 55
41static char const lcd_ascii[] = 56static char const lcd_ascii[] =
42 { 57{
43/*****************************************************************************************/ 58/*****************************************************************************************/
44/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ 59/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
45/* ************************************************************************************/ 60/* ************************************************************************************/
@@ -91,45 +106,314 @@ static char const lcd_ascii[] =
91# endif 106# endif
92 107
93void lcd_puts (char const *string) 108void lcd_puts (char const *string)
94 { 109{
95 while (*string) 110 while (*string)
96 lcd_data (LCD_ASCII(*string++)); 111 lcd_data (LCD_ASCII(*string++));
97 } 112}
98 113
99void lcd_putns (char const *string,int n) 114void lcd_putns (char const *string,int n)
100 { 115{
101 while (n--) 116 while (n--)
102 lcd_data (LCD_ASCII(*string++)); 117 lcd_data (LCD_ASCII(*string++));
103 } 118}
104 119
105void lcd_putc (int character) 120void lcd_putc (int character)
106 { 121{
107 lcd_data (LCD_ASCII(character)); 122 lcd_data (LCD_ASCII(character));
108 } 123}
109 124
110void lcd_pattern (int which,char const *pattern,int count) 125void lcd_pattern (int which,char const *pattern,int count)
126{
127 lcd_instruction (LCD_PRAM|which);
128 lcd_copy ((void *)pattern,count);
129}
130
131void lcd_puthex (unsigned int value,int digits)
132{
133 switch (digits) {
134 case 8:
135 lcd_puthex (value >> 16,4);
136 case 4:
137 lcd_puthex (value >> 8,2);
138 case 2:
139 lcd_puthex (value >> 4,1);
140 case 1:
141 value &= 15;
142 lcd_putc (value+((value < 10) ? '0' : ('A'-10)));
143 }
144}
145
146
147/* HAVE_LCD_CHARCELLS */
148#elif defined(HAVE_LCD_BITMAP)
149
150/*
151 * All bitmaps have this format:
152 * Bits within a byte are arranged veritcally, LSB at top.
153 * Bytes are stored in column-major format, with byte 0 at top left,
154 * byte 1 is 2nd from top, etc. Bytes following left-most column
155 * starts 2nd left column, etc.
156 *
157 * Note: The HW takes bitmap bytes in row-major order.
158 *
159 * Memory copy of display bitmap
160 */
161unsigned char display[DISP_X][DISP_Y/8];
162
163//
164// ASCII character generation tables
165//
166// This contains only the printable characters (0x20-0x7f).
167// Each element in this table is a character pattern bitmap.
168//
169#define ASCII_MIN 0x20 // First char in table
170#define ASCII_MAX 0x7f // Last char in table
171
172extern const unsigned char char_gen_6x8[][5][1];
173extern const unsigned char char_gen_8x12[][7][2];
174extern const unsigned char char_gen_12x16[][11][2];
175
176
177/* All zeros and ones bitmaps for area filling */
178static const unsigned char zeros[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00 };
180static const unsigned char ones[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
181 0xff, 0xff };
182
183static int lcd_y; /* Current pixel row */
184static int lcd_x; /* Current pixel column */
185static int lcd_size; /* Current font width */
186
187#ifndef SIMULATOR
188
189/*
190 * Initialize LCD
191 */
192void lcd_init (void)
193{
194 // Initialize PB0-3 as output pins
195 PBCR2 &= 0xff00; // MD = 00
196 PBIOR |= 0x000f; // IOR = 1
197
198 // Initialize LCD
199 lcd_write (TRUE, LCD_CNTL_RESET);
200 lcd_write (TRUE, LCD_CNTL_POWER);
201 lcd_write (TRUE, LCD_CNTL_SEGREMAP);
202 lcd_write (TRUE, LCD_CNTL_OUTSCAN);
203 lcd_write (TRUE, LCD_CNTL_CONTRAST);
204 lcd_write (TRUE, 0x30); // Contrast parameter
205 lcd_write (TRUE, LCD_CNTL_DISPON);
206
207 lcd_clear_display();
208 lcd_update();
209}
210
211/*
212 * Update the display.
213 * This must be called after all other LCD funtions that change the display.
214 */
215void lcd_update (void)
216{
217 int x, y;
218
219 /* Copy display bitmap to hardware */
220 for (y = 0; y < DISP_Y/8; y++)
111 { 221 {
112 lcd_instruction (LCD_PRAM|which); 222 lcd_write (TRUE, LCD_CNTL_PAGE | (y & 0xf));
113 lcd_copy ((void *)pattern,count); 223 lcd_write (TRUE, LCD_CNTL_HIGHCOL);
224 lcd_write (TRUE, LCD_CNTL_LOWCOL);
225
226 for (x = 0; x < DISP_X; x++)
227 lcd_write (FALSE, display[x][y]);
114 } 228 }
229}
115 230
116#else 231static void lcd_write (BOOL command, int value)
117# error "JBR : FIX ME" 232{
118#endif 233 int bit;
119 234
120void lcd_puthex (unsigned int value,int digits) 235 /* Enable chip select, set DC if data */
236 PBDR &= ~(PBDR_LCD_CS1|PBDR_LCD_DC);
237 if (!command)
238 PBDR |= PBDR_LCD_DC;
239
240 /* Send each bit, starting with MSB */
241 for (bit = 0x80; bit > 0; bit >>= 1)
121 { 242 {
122 switch (digits) 243 PBDR &= ~(PBDR_LCD_SDA|PBDR_LCD_SCK);
123 { 244 if (value & bit)
124 case 8: 245 PBDR |= PBDR_LCD_SDA;
125 lcd_puthex (value >> 16,4); 246 PBDR |= PBDR_LCD_SCK;
126 case 4:
127 lcd_puthex (value >> 8,2);
128 case 2:
129 lcd_puthex (value >> 4,1);
130 case 1:
131 value &= 15;
132 lcd_putc (value+((value < 10) ? '0' : ('A'-10)));
133 }
134 } 247 }
248
249 /* Disable chip select */
250 PBDR |= PBDR_LCD_CS1;
251}
252
253#endif /* SIMULATOR */
254
255/*
256 * Clear the display
257 */
258void lcd_clear_display (void)
259{
260 lcd_position (0, 0, 8);
261 memset (display, 0, sizeof display);
262}
263
264/*
265 * Set current x,y position and font size
266 */
267void lcd_position (int x, int y, int size)
268{
269 if (x >= 0 && x < DISP_X && y >= 0 && y < DISP_Y)
270 {
271 lcd_x = x;
272 lcd_y = y;
273 }
274
275 lcd_size = size;
276}
277
278/*
279 * Display a string at current position and size
280 */
281void lcd_string (const char *str)
282{
283 int x = lcd_x;
284 int nx = lcd_size;
285 int ny, ch;
286 const unsigned char *src;
287
288 if (nx == 12)
289 ny = 16;
290 else if (nx == 8)
291 ny = 12;
292 else
293 {
294 nx = 6;
295 ny = 8;
296 }
297
298 while ((ch = *str++) != '\0')
299 {
300 if (ch == '\n' || lcd_x + nx > DISP_X)
301 {
302 /* Wrap to next line */
303 lcd_x = x;
304 lcd_y += ny;
305 }
306
307 if (lcd_y + ny > DISP_Y)
308 return;
309
310 /* Limit to char generation table */
311 if (ch >= ASCII_MIN && ch <= ASCII_MAX)
312 {
313 if (nx == 12)
314 src = char_gen_12x16[ch-ASCII_MIN][0];
315 else if (nx == 8)
316 src = char_gen_8x12[ch-ASCII_MIN][0];
317 else
318 src = char_gen_6x8[ch-ASCII_MIN][0];
319
320 lcd_bitmap (src, lcd_x, lcd_y, nx-1, ny, TRUE);
321 lcd_bitmap (zeros, lcd_x+nx-1, lcd_y, 1, ny, TRUE);
322
323 lcd_x += nx;
324 }
325 }
326}
327
328/*
329 * Display a bitmap at (x, y), size (nx, ny)
330 * clear is TRUE to clear destination area first
331 */
332void lcd_bitmap (const unsigned char *src, int x, int y, int nx, int ny,
333 bool clear)
334{
335 unsigned char *dst;
336 unsigned char *dst2 = &display[x][y/8];
337 unsigned int data, mask, mask2, mask3, mask4;
338 int shift = y & 7;
339
340 ny += shift;
341
342 /* Calculate bit masks */
343 mask4 = ~(0xfe << ((ny-1) & 7));
344 if (clear)
345 {
346 mask = ~(0xff << shift);
347 mask2 = 0;
348 mask3 = ~mask4;
349 if (ny <= 8)
350 mask3 |= mask;
351 }
352 else
353 mask = mask2 = mask3 = 0xff;
354
355 /* Loop for each column */
356 for (x = 0; x < nx; x++)
357 {
358 dst = dst2;
359 dst2 += DISP_Y/8;
360 data = 0;
361 y = 0;
362
363 if (ny > 8)
364 {
365 /* First partial row */
366 data = *src++ << shift;
367 *dst = (*dst & mask) ^ data;
368 data >>= 8;
369 dst++;
370
371 /* Intermediate rows */
372 for (y = 8; y < ny-8; y += 8)
373 {
374 data |= *src++ << shift;
375 *dst = (*dst & mask2) ^ data;
376 data >>= 8;
377 dst++;
378 }
379 }
380
381 /* Last partial row */
382 if (y + shift < ny)
383 data |= *src++ << shift;
384 *dst = (*dst & mask3) ^ (data & mask4);
385 }
386}
387
388/*
389 * Clear a rectangular area at (x, y), size (nx, ny)
390 */
391void lcd_clearrect (int x, int y, int nx, int ny)
392{
393 int i;
394 for (i = 0; i < nx; i++)
395 lcd_bitmap (zeros, x+i, y, 1, ny, TRUE);
396}
397
398/*
399 * Fill a rectangular area at (x, y), size (nx, ny)
400 */
401void lcd_fillrect (int x, int y, int nx, int ny)
402{
403 int i;
404 for (i = 0; i < nx; i++)
405 lcd_bitmap (ones, x+i, y, 1, ny, TRUE);
406}
407
408/* Invert a rectangular area at (x, y), size (nx, ny) */
409void lcd_invertrect (int x, int y, int nx, int ny)
410{
411 int i;
412 for (i = 0; i < nx; i++)
413 lcd_bitmap (ones, x+i, y, 1, ny, FALSE);
414}
415
416#else
417/* no LCD defined, no code to use */
418#endif
135 419