summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/lcd-h100-remote.c172
-rw-r--r--firmware/export/kernel.h2
-rw-r--r--firmware/export/lcd-remote.h2
3 files changed, 125 insertions, 51 deletions
diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c
index f0759d6328..2850712a91 100644
--- a/firmware/drivers/lcd-h100-remote.c
+++ b/firmware/drivers/lcd-h100-remote.c
@@ -29,12 +29,9 @@
29#include "system.h" 29#include "system.h"
30#include "font.h" 30#include "font.h"
31 31
32/* All zeros and ones bitmaps for area filling */ 32/* All zeros and ones bitmaps for area filling */
33static const unsigned char zeros[16] = { 33static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 34static const unsigned char ones[8] = {
35};
36static const unsigned char ones[16] = {
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
39}; 36};
40 37
@@ -66,6 +63,16 @@ struct scrollinfo {
66static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ 63static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
67 64
68#ifndef SIMULATOR 65#ifndef SIMULATOR
66static int countdown; /* for remote plugging debounce */
67static bool last_remote_status = false;
68static bool init_remote = false; /* scroll thread should init lcd */
69static bool remote_initialized = false;
70
71/* cached settings values, for hotplug init */
72static bool cached_invert = false;
73static int cached_contrast = 32;
74static int cached_roll = 0;
75
69static void scroll_thread(void); 76static void scroll_thread(void);
70static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; 77static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
71#endif 78#endif
@@ -209,18 +216,25 @@ void lcd_remote_write_command_ex(int cmd, int data)
209 216
210void lcd_remote_powersave(bool on) 217void lcd_remote_powersave(bool on)
211{ 218{
212 lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | (on ? 0 : 1)); 219 if (remote_initialized)
213 lcd_remote_write_command(LCD_REMOTE_CNTL_ENTIRE_ON_OFF | (on ? 1 : 0)); 220 {
221 lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | (on ? 0 : 1));
222 lcd_remote_write_command(LCD_REMOTE_CNTL_ENTIRE_ON_OFF | (on ? 1 : 0));
223 }
214} 224}
215 225
216void lcd_remote_set_contrast(int val) 226void lcd_remote_set_contrast(int val)
217{ 227{
218 lcd_remote_write_command_ex(LCD_REMOTE_CNTL_SELECT_VOLTAGE, val); 228 cached_contrast = val;
229 if (remote_initialized)
230 lcd_remote_write_command_ex(LCD_REMOTE_CNTL_SELECT_VOLTAGE, val);
219} 231}
220 232
221void lcd_remote_set_invert_display(bool yesno) 233void lcd_remote_set_invert_display(bool yesno)
222{ 234{
223 lcd_remote_write_command(LCD_REMOTE_CNTL_REVERSE_ON_OFF | yesno); 235 cached_invert = yesno;
236 if (remote_initialized)
237 lcd_remote_write_command(LCD_REMOTE_CNTL_REVERSE_ON_OFF | yesno);
224} 238}
225 239
226int lcd_remote_default_contrast(void) 240int lcd_remote_default_contrast(void)
@@ -377,42 +391,13 @@ void lcd_remote_clear_display(void)
377} 391}
378 392
379#ifndef SIMULATOR 393#ifndef SIMULATOR
380/*
381 * Update the display.
382 * This must be called after all other LCD functions that change the display.
383 */
384void lcd_remote_update (void) __attribute__ ((section (".icode")));
385void lcd_remote_update (void)
386{
387 int y;
388 394
389 /* Copy display bitmap to hardware */ 395static void remote_lcd_init(void)
390 for (y = 0; y < LCD_REMOTE_HEIGHT / 8; y++)
391 {
392 lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y);
393 lcd_remote_write_command_ex(0x10, 0x04);
394 lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH);
395 }
396}
397
398void lcd_remote_init(void)
399{ 396{
400 GPIO_FUNCTION |= 0x10010800; /* GPIO11: Backlight
401 GPIO16: RS
402 GPIO28: CLK */
403
404 GPIO1_FUNCTION |= 0x00040004; /* GPIO34: CS
405 GPIO50: Data */
406 GPIO_ENABLE |= 0x10010800;
407 GPIO1_ENABLE |= 0x00040004;
408
409 CLK_LO;
410 CS_HI;
411
412 lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE); 397 lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE);
413 lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_REVERSE); 398 lcd_remote_write_command(LCD_REMOTE_CNTL_SHL_REVERSE);
414 lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0); 399 lcd_remote_write_command(LCD_REMOTE_CNTL_SELECT_BIAS | 0x0);
415 400
416 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x5); 401 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x5);
417 sleep(1); 402 sleep(1);
418 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6); 403 lcd_remote_write_command(LCD_REMOTE_CNTL_POWER_CONTROL | 0x6);
@@ -426,18 +411,91 @@ void lcd_remote_init(void)
426 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line 411 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
427 lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address 412 lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | 0x0); // page address
428 lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB 413 lcd_remote_write_command_ex(0x10, 0x00); // Column MSB + LSB
429 414
430 lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1); 415 lcd_remote_write_command(LCD_REMOTE_CNTL_DISPLAY_ON_OFF | 1);
431 416
432 lcd_remote_clear_display(); 417 remote_initialized = true;
433 lcd_remote_update(); 418
419 lcd_remote_set_contrast(cached_contrast);
420 lcd_remote_set_invert_display(cached_invert);
421 lcd_remote_roll(cached_roll);
422}
423
424static void remote_tick(void)
425{
426 bool current_status;
427
428 current_status = ((GPIO_READ & 0x40000000) == 0);
429 /* Only report when the status has changed */
430 if (current_status != last_remote_status)
431 {
432 last_remote_status = current_status;
433 countdown = current_status ? HZ : 1;
434 }
435 else
436 {
437 /* Count down until it gets negative */
438 if (countdown >= 0)
439 countdown--;
440
441 if (countdown == 0)
442 {
443 if (current_status)
444 {
445 init_remote = true;
446 /* request init in scroll_thread */
447 }
448 else
449 {
450 CLK_LO;
451 CS_HI;
452 remote_initialized = false;
453 }
454 }
455 }
456}
457
458void lcd_remote_init(void)
459{
460 GPIO_FUNCTION |= 0x10010800; /* GPIO11: Backlight
461 GPIO16: RS
462 GPIO28: CLK */
434 463
464 GPIO1_FUNCTION |= 0x00040004; /* GPIO34: CS
465 GPIO50: Data */
466 GPIO_ENABLE |= 0x10010800;
467 GPIO1_ENABLE |= 0x00040004;
468
469 lcd_remote_clear_display();
470
471 tick_add_task(remote_tick);
435 create_thread(scroll_thread, scroll_stack, 472 create_thread(scroll_thread, scroll_stack,
436 sizeof(scroll_stack), scroll_name); 473 sizeof(scroll_stack), scroll_name);
437} 474}
438 475
439 476
440/* 477/*
478 * Update the display.
479 * This must be called after all other LCD functions that change the display.
480 */
481void lcd_remote_update (void) __attribute__ ((section (".icode")));
482void lcd_remote_update (void)
483{
484 int y;
485
486 if (!remote_initialized)
487 return;
488
489 /* Copy display bitmap to hardware */
490 for (y = 0; y < LCD_REMOTE_HEIGHT / 8; y++)
491 {
492 lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y);
493 lcd_remote_write_command_ex(0x10, 0x04);
494 lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH);
495 }
496}
497
498/*
441 * Update a fraction of the display. 499 * Update a fraction of the display.
442 */ 500 */
443void lcd_remote_update_rect (int, int, int, int) __attribute__ ((section (".icode"))); 501void lcd_remote_update_rect (int, int, int, int) __attribute__ ((section (".icode")));
@@ -445,6 +503,9 @@ void lcd_remote_update_rect (int x_start, int y,
445 int width, int height) 503 int width, int height)
446{ 504{
447 int ymax; 505 int ymax;
506
507 if (!remote_initialized)
508 return;
448 509
449 /* The Y coordinates have to work on even 8 pixel rows */ 510 /* The Y coordinates have to work on even 8 pixel rows */
450 ymax = (y + height-1)/8; 511 ymax = (y + height-1)/8;
@@ -478,13 +539,18 @@ void lcd_remote_update_rect (int x_start, int y,
478void lcd_remote_roll(int lines) 539void lcd_remote_roll(int lines)
479{ 540{
480 char data[2]; 541 char data[2];
542
543 cached_roll = lines;
481 544
482 lines &= LCD_REMOTE_HEIGHT-1; 545 if (remote_initialized)
483 data[0] = lines & 0xff; 546 {
484 data[1] = lines >> 8; 547 lines &= LCD_REMOTE_HEIGHT-1;
548 data[0] = lines & 0xff;
549 data[1] = lines >> 8;
485 550
486 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line 551 lcd_remote_write_command(LCD_REMOTE_CNTL_INIT_LINE | 0x0); // init line
487 lcd_remote_write_data(data, 2); 552 lcd_remote_write_data(data, 2);
553 }
488} 554}
489 555
490#endif 556#endif
@@ -925,6 +991,14 @@ static void scroll_thread(void)
925 scrolling_lines = 0; 991 scrolling_lines = 0;
926 992
927 while ( 1 ) { 993 while ( 1 ) {
994
995 if (init_remote) /* request to initialize the remote lcd */
996 {
997 init_remote = false; /* clear request */
998 remote_lcd_init();
999 lcd_remote_update();
1000 }
1001
928 for ( index = 0; index < SCROLLABLE_LINES; index++ ) { 1002 for ( index = 0; index < SCROLLABLE_LINES; index++ ) {
929 /* really scroll? */ 1003 /* really scroll? */
930 if ( !(scrolling_lines&(1<<index)) ) 1004 if ( !(scrolling_lines&(1<<index)) )
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index ed535c6d20..be4fd0bc73 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -27,7 +27,7 @@
27 27
28#define HZ 100 /* number of ticks per second */ 28#define HZ 100 /* number of ticks per second */
29 29
30#define MAX_NUM_TICK_TASKS 4 30#define MAX_NUM_TICK_TASKS 5
31 31
32#define QUEUE_LENGTH 16 /* MUST be a power of 2 */ 32#define QUEUE_LENGTH 16 /* MUST be a power of 2 */
33#define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1) 33#define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1)
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index 9314c587d6..f57a6ee4ba 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -77,7 +77,7 @@ extern void lcd_remote_clearline( int x1, int y1, int x2, int y2 );
77extern void lcd_remote_drawpixel(int x, int y); 77extern void lcd_remote_drawpixel(int x, int y);
78extern void lcd_remote_clearpixel(int x, int y); 78extern void lcd_remote_clearpixel(int x, int y);
79extern void lcd_remote_invertpixel(int x, int y); 79extern void lcd_remote_invertpixel(int x, int y);
80//extern void lcd_roll(int pixels); 80extern void lcd_remote_roll(int pixels);
81extern void lcd_remote_set_invert_display(bool yesno); 81extern void lcd_remote_set_invert_display(bool yesno);
82//extern void lcd_set_flip(bool yesno); 82//extern void lcd_set_flip(bool yesno);
83extern void lcd_remote_bidir_scroll(int threshold); 83extern void lcd_remote_bidir_scroll(int threshold);