Add configurable options for HD44780 LCD display columns and rows.
[bertos.git] / bertos / mware / blanker.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
30  * Copyright 2001 Bernie Innocenti <bernie@codewiz.org>
31  * -->
32  *
33  * \brief Display Blanker (implementation).
34  *
35  * \version $Id$
36  *
37  * \author Bernie Innocenti <bernie@codewiz.org>
38  */
39
40 #include "blanker.h"
41 #include "hw/hw_blanker.h"
42
43 #include <drv/kbd.h>
44 #include <drv/timer.h>
45
46 /* Time without input events before starting blanker */
47 #define BLK_BLANKTIMEOUT        (15 * 1000)     /* ms */
48
49
50 #warning FIXME:Revise me!
51
52 /** Keyboard event handler to listen for key presses in blanker. */
53 static KbdHandler blk_KbdHandler;
54
55 /** Time since last key event. */
56 static ticks_t blk_lastevent;
57
58 /** Display blanking function is enabled. */
59 static bool blk_enabled;
60
61 /** Display blanker is engaged right now. */
62 static bool blk_active;
63
64
65 static bool blk_on(void)
66 {
67         if (!blk_active)
68         {
69                 blk_active = true;
70                 BLK_LCDOFF;
71         }
72         return true;
73 }
74
75
76 static void blk_off(void)
77 {
78         if (blk_active)
79         {
80                 blk_active = false;
81                 BLK_LCDON;
82         }
83 }
84
85
86 void blk_retrigger(void)
87 {
88         blk_lastevent = timer_clock();
89         blk_off();
90 }
91
92 #if 0
93 /**
94  * Matrix-like screen saver effect
95  */
96 static void blk_hack(void)
97 {
98         static signed char blk_colstart[CONFIG_LCD_COLS];
99         UBYTE row, col;
100
101
102         if (rand()%3 == 0)
103         {
104                 /* Modify one column */
105                 col = rand() % CONFIG_LCD_COLS;
106                 blk_colstart[col] += rand() % 12 - 5;
107         }
108
109         for (col = 0; col < CONFIG_LCD_COLS; ++col)
110         {
111                 if (blk_colstart[col] > 0)
112                 {
113                         --blk_colstart[col];
114
115                         /* Scroll down */
116                         for(row = CONFIG_LCD_ROWS-1; row; --row)
117                         {
118                                 lcd_SetAddr(blk_layer, LCD_POS(col,row));
119                                 lcd_PutChar(blk_layer->Buf[LCD_POS(col,row-1)], blk_layer);
120                         }
121
122                         /* Add new kanji */
123                         lcd_SetAddr(blk_layer, LCD_POS(col,0));
124                         lcd_PutChar((char)(rand() % 127 + 128), blk_layer);
125                 }
126                 else if (blk_colstart[col] < 0)
127                 {
128                         ++blk_colstart[col];
129
130                         /* Clear tail */
131                         for(row = 0; row < CONFIG_LCD_ROWS; ++row)
132                         {
133                                 if (blk_layer->Buf[LCD_POS(col,row)] != ' ')
134                                 {
135                                         lcd_SetAddr(blk_layer, LCD_POS(col,row));
136                                         lcd_PutChar(' ', blk_layer);
137                                         break;
138                                 }
139                         }
140                 }
141         }
142 }
143 #endif
144
145
146 static keymask_t blk_handlerFunc(keymask_t key)
147 {
148         /* key used to turn off blanker */
149         static keymask_t offkey;
150
151         ticks_t now = timer_clock();
152
153         /* If key pressed */
154         if (key != 0)
155         {
156                 blk_lastevent = now;
157                 if (blk_active)
158                 {
159                         blk_off();
160
161                         /* remember and eat key event */
162                         offkey = key;
163                         key = 0;
164                 }
165                 else if (key == offkey)
166                 {
167                         /* keep eating the key until released */
168                         key = 0;
169                 }
170
171                 /* pass key through */
172                 return key;
173         }
174
175         /* reset off key */
176         offkey = 0;
177
178         /* Blank timeout reached? */
179         if (now - blk_lastevent > ms_to_ticks(BLK_BLANKTIMEOUT))
180         {
181                 /* Enable blanker unless already done */
182                 if (!blk_active && !blk_on())
183                         return 0;
184
185 #if 0
186                 /* Do some nice visual effect */
187                 blk_hack();
188 #endif /* _DEBUG */
189         }
190
191         return 0;
192 }
193
194
195 void blk_enable(void)
196 {
197         if (!blk_enabled)
198         {
199                 blk_active = false;
200                 blk_lastevent = timer_clock();
201
202                 /* Add display blanker handler */
203                 blk_KbdHandler.hook = blk_handlerFunc;
204                 blk_KbdHandler.pri = 100; /* high priority */
205                 blk_KbdHandler.flags = KHF_RAWKEYS;
206                 kbd_addHandler(&blk_KbdHandler);
207
208                 blk_enabled = true;
209         }
210 }
211
212
213 void blk_disable(void)
214 {
215         if (blk_enabled)
216         {
217                 kbd_remHandler(&blk_KbdHandler);
218                 blk_off();
219                 blk_enabled = false;
220         }
221 }
222