summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-charcell.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-charcell.c')
-rw-r--r--firmware/drivers/lcd-charcell.c184
1 files changed, 63 insertions, 121 deletions
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c
index efc9aa5b1f..0fd41481c5 100644
--- a/firmware/drivers/lcd-charcell.c
+++ b/firmware/drivers/lcd-charcell.c
@@ -29,10 +29,10 @@
29#include "system.h" 29#include "system.h"
30#include "lcd-charcell.h" 30#include "lcd-charcell.h"
31#include "rbunicode.h" 31#include "rbunicode.h"
32#include "scroll_engine.h"
32 33
33/** definitions **/ 34/** definitions **/
34 35
35#define SCROLLABLE_LINES LCD_HEIGHT
36#define VARIABLE_XCHARS 16 /* number of software user-definable characters */ 36#define VARIABLE_XCHARS 16 /* number of software user-definable characters */
37/* There must be mappings for this many characters in the 0xe000 unicode range 37/* There must be mappings for this many characters in the 0xe000 unicode range
38 * in lcd-charset-<target>.c */ 38 * in lcd-charset-<target>.c */
@@ -55,24 +55,6 @@ static int xspace; /* stores xhcar id of ' ' - often needed */
55static int xmargin = 0; 55static int xmargin = 0;
56static int ymargin = 0; 56static int ymargin = 0;
57 57
58/* scrolling */
59static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
60static void scroll_thread(void);
61static char scroll_stack[DEFAULT_STACK_SIZE];
62static const char scroll_name[] = "scroll";
63static int scroll_ticks = 12; /* # of ticks between updates */
64static int scroll_delay = HZ/2; /* delay before starting scroll */
65static int bidir_limit = 50; /* percent */
66static int jump_scroll_delay = HZ/4; /* delay between jump scroll jumps */
67static int jump_scroll = 0; /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */
68static struct scrollinfo scroll[SCROLLABLE_LINES];
69
70static const char scroll_tick_table[16] = {
71 /* Hz values:
72 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */
73 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3
74};
75
76/* LCD init */ 58/* LCD init */
77void lcd_init (void) 59void lcd_init (void)
78{ 60{
@@ -81,11 +63,7 @@ void lcd_init (void)
81 memset(lcd_patterns, 0, sizeof(lcd_patterns)); 63 memset(lcd_patterns, 0, sizeof(lcd_patterns));
82 xspace = find_xchar(' '); 64 xspace = find_xchar(' ');
83 memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer)); 65 memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer));
84 66 scroll_init();
85 create_thread(scroll_thread, scroll_stack,
86 sizeof(scroll_stack), scroll_name
87 IF_PRIO(, PRIORITY_USER_INTERFACE)
88 IF_COP(, CPU, false));
89} 67}
90 68
91/** parameter handling **/ 69/** parameter handling **/
@@ -336,7 +314,7 @@ void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
336 lcd_cursor.x = x; 314 lcd_cursor.x = x;
337 lcd_cursor.y = y; 315 lcd_cursor.y = y;
338 lcd_cursor.downcount = 0; 316 lcd_cursor.downcount = 0;
339 lcd_cursor.divider = MAX((HZ/2) / scroll_ticks, 1); 317 lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1);
340} 318}
341 319
342/* Remove the cursor */ 320/* Remove the cursor */
@@ -398,7 +376,7 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset)
398 return; 376 return;
399 377
400 /* make sure scrolling is turned off on the line we are updating */ 378 /* make sure scrolling is turned off on the line we are updating */
401 scrolling_lines &= ~(1 << y); 379 lcd_scroll_info.lines &= ~(1 << y);
402 380
403 x = lcd_putsxyofs(x, y, offset, str); 381 x = lcd_putsxyofs(x, y, offset, str);
404 while (x < LCD_WIDTH) 382 while (x < LCD_WIDTH)
@@ -406,37 +384,6 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset)
406} 384}
407 385
408/** scrolling **/ 386/** scrolling **/
409
410void lcd_stop_scroll(void)
411{
412 scrolling_lines=0;
413}
414
415void lcd_scroll_speed(int speed)
416{
417 scroll_ticks = scroll_tick_table[speed];
418}
419
420void lcd_scroll_delay(int ms)
421{
422 scroll_delay = ms / (HZ / 10);
423}
424
425void lcd_bidir_scroll(int percent)
426{
427 bidir_limit = percent;
428}
429
430void lcd_jump_scroll(int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */
431{
432 jump_scroll = mode;
433}
434
435void lcd_jump_scroll_delay(int ms)
436{
437 jump_scroll_delay = ms / (HZ / 10);
438}
439
440void lcd_puts_scroll(int x, int y, const unsigned char *string) 387void lcd_puts_scroll(int x, int y, const unsigned char *string)
441{ 388{
442 lcd_puts_scroll_offset(x, y, string, 0); 389 lcd_puts_scroll_offset(x, y, string, 0);
@@ -448,11 +395,11 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
448 struct scrollinfo* s; 395 struct scrollinfo* s;
449 int len; 396 int len;
450 397
451 if(y>=SCROLLABLE_LINES) return; 398 if(y>=LCD_SCROLLABLE_LINES) return;
452 399
453 s = &scroll[y]; 400 s = &lcd_scroll_info.scroll[y];
454 401
455 s->start_tick = current_tick + scroll_delay; 402 s->start_tick = current_tick + lcd_scroll_info.delay;
456 403
457 lcd_puts_offset(x, y, string, offset); 404 lcd_puts_offset(x, y, string, offset);
458 len = utf8length(string); 405 len = utf8length(string);
@@ -469,9 +416,10 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
469 s->len = utf8length(s->line); 416 s->len = utf8length(s->line);
470 417
471 /* scroll bidirectional or forward only depending on the string width */ 418 /* scroll bidirectional or forward only depending on the string width */
472 if (bidir_limit) 419 if (lcd_scroll_info.bidir_limit)
473 { 420 {
474 s->bidir = s->len < (LCD_WIDTH - xmargin) * (100 + bidir_limit) / 100; 421 s->bidir = s->len < (LCD_WIDTH - xmargin) *
422 (100 + lcd_scroll_info.bidir_limit) / 100;
475 } 423 }
476 else 424 else
477 s->bidir = false; 425 s->bidir = false;
@@ -489,83 +437,77 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
489 s->offset = offset; 437 s->offset = offset;
490 s->startx = xmargin + x; 438 s->startx = xmargin + x;
491 s->backward = false; 439 s->backward = false;
492 scrolling_lines |= (1<<y); 440 lcd_scroll_info.lines |= (1<<y);
493 } 441 }
494 else 442 else
495 /* force a bit switch-off since it doesn't scroll */ 443 /* force a bit switch-off since it doesn't scroll */
496 scrolling_lines &= ~(1<<y); 444 lcd_scroll_info.lines &= ~(1<<y);
497} 445}
498 446
499static void scroll_thread(void) 447void lcd_scroll_fn(void)
500{ 448{
501 struct scrollinfo* s; 449 struct scrollinfo* s;
502 int index; 450 int index;
503 int xpos, ypos; 451 int xpos, ypos;
504 bool update; 452 bool update;
505 453
506 /* initialize scroll struct array */ 454 update = false;
507 scrolling_lines = 0; 455 for (index = 0; index < LCD_SCROLLABLE_LINES; index++)
508
509 while (1)
510 { 456 {
511 update = false; 457 /* really scroll? */
512 for (index = 0; index < SCROLLABLE_LINES; index++) 458 if ((lcd_scroll_info.lines & (1 << index)) == 0)
459 continue;
460
461 s = &lcd_scroll_info.scroll[index];
462
463 /* check pause */
464 if (TIME_BEFORE(current_tick, s->start_tick))
465 continue;
466
467 if (s->backward)
468 s->offset--;
469 else
470 s->offset++;
471
472 xpos = s->startx;
473 ypos = ymargin + index;
474
475 if (s->bidir) /* scroll bidirectional */
513 { 476 {
514 /* really scroll? */ 477 if (s->offset <= 0) {
515 if (!(scrolling_lines&(1<<index))) 478 /* at beginning of line */
516 continue; 479 s->offset = 0;
517 480 s->backward = false;
518 s = &scroll[index]; 481 s->start_tick = current_tick + lcd_scroll_info.delay * 2;
519
520 /* check pause */
521 if (TIME_BEFORE(current_tick, s->start_tick))
522 continue;
523
524 if (s->backward)
525 s->offset--;
526 else
527 s->offset++;
528
529 xpos = s->startx;
530 ypos = ymargin + index;
531
532 if (s->bidir) /* scroll bidirectional */
533 {
534 if (s->offset <= 0)
535 {
536 /* at beginning of line */
537 s->offset = 0;
538 s->backward = false;
539 s->start_tick = current_tick + scroll_delay * 2;
540 }
541 if (s->offset >= s->len - (LCD_WIDTH - xpos))
542 {
543 /* at end of line */
544 s->offset = s->len - (LCD_WIDTH - xpos);
545 s->backward = true;
546 s->start_tick = current_tick + scroll_delay * 2;
547 }
548 } 482 }
549 else /* scroll forward the whole time */ 483 if (s->offset >= s->len - (LCD_WIDTH - xpos)) {
550 { 484 /* at end of line */
551 if (s->offset >= s->len) 485 s->offset = s->len - (LCD_WIDTH - xpos);
552 s->offset -= s->len; 486 s->backward = true;
487 s->start_tick = current_tick + lcd_scroll_info.delay * 2;
553 } 488 }
554 lcd_putsxyofs(xpos, ypos, s->offset, s->line);
555 update = true;
556 } 489 }
557 if (lcd_cursor.enabled) 490 else /* scroll forward the whole time */
558 { 491 {
559 if (--lcd_cursor.downcount <= 0) 492 if (s->offset >= s->len)
560 { 493 s->offset -= s->len;
561 lcd_cursor.downcount = lcd_cursor.divider;
562 lcd_cursor.visible = !lcd_cursor.visible;
563 update = true;
564 }
565 } 494 }
566 if (update)
567 lcd_update();
568 495
569 sleep(scroll_ticks); 496 lcd_putsxyofs(xpos, ypos, s->offset, s->line);
497 update = true;
498 }
499
500 if (lcd_cursor.enabled)
501 {
502 if (--lcd_cursor.downcount <= 0)
503 {
504 lcd_cursor.downcount = lcd_cursor.divider;
505 lcd_cursor.visible = !lcd_cursor.visible;
506 update = true;
507 }
570 } 508 }
509
510 if (update)
511 lcd_update();
571} 512}
513