diff options
Diffstat (limited to 'firmware/drivers/lcd-charcell.c')
-rw-r--r-- | firmware/drivers/lcd-charcell.c | 184 |
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 */ | |||
55 | static int xmargin = 0; | 55 | static int xmargin = 0; |
56 | static int ymargin = 0; | 56 | static int ymargin = 0; |
57 | 57 | ||
58 | /* scrolling */ | ||
59 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | ||
60 | static void scroll_thread(void); | ||
61 | static char scroll_stack[DEFAULT_STACK_SIZE]; | ||
62 | static const char scroll_name[] = "scroll"; | ||
63 | static int scroll_ticks = 12; /* # of ticks between updates */ | ||
64 | static int scroll_delay = HZ/2; /* delay before starting scroll */ | ||
65 | static int bidir_limit = 50; /* percent */ | ||
66 | static int jump_scroll_delay = HZ/4; /* delay between jump scroll jumps */ | ||
67 | static int jump_scroll = 0; /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ | ||
68 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
69 | |||
70 | static 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 */ |
77 | void lcd_init (void) | 59 | void 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 | |||
410 | void lcd_stop_scroll(void) | ||
411 | { | ||
412 | scrolling_lines=0; | ||
413 | } | ||
414 | |||
415 | void lcd_scroll_speed(int speed) | ||
416 | { | ||
417 | scroll_ticks = scroll_tick_table[speed]; | ||
418 | } | ||
419 | |||
420 | void lcd_scroll_delay(int ms) | ||
421 | { | ||
422 | scroll_delay = ms / (HZ / 10); | ||
423 | } | ||
424 | |||
425 | void lcd_bidir_scroll(int percent) | ||
426 | { | ||
427 | bidir_limit = percent; | ||
428 | } | ||
429 | |||
430 | void lcd_jump_scroll(int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ | ||
431 | { | ||
432 | jump_scroll = mode; | ||
433 | } | ||
434 | |||
435 | void lcd_jump_scroll_delay(int ms) | ||
436 | { | ||
437 | jump_scroll_delay = ms / (HZ / 10); | ||
438 | } | ||
439 | |||
440 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | 387 | void 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 | ||
499 | static void scroll_thread(void) | 447 | void 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 | |||