4 * This file is part of BeRTOS.
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.
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.
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
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.
29 * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
30 * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
36 * \author Bernardo Innocenti <bernie@develer.com>
38 * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
43 *#* Revision 1.1 2006/01/16 03:51:35 bernie
44 *#* Add LCD Qt emulator.
50 #include <qsizepolicy.h>
57 #define LCD_FG_COLOR 0x0, 0x0, 0x0
58 #define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
61 EmulLCD::EmulLCD(QWidget *parent, const char *name) :
62 QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
63 lcd_font("courier", 18),
64 fg_color(LCD_FG_COLOR),
65 bg_color(LCD_BG_COLOR),
73 "01234567890123456789"
74 "abcdefghijhlmnopqrst"
75 "ABCDEFGHIJKLMNOPQRST"
76 "!@#$%^&*()_+|{}':?><",
80 lcd_font.setFixedPitch(true);
83 // get exact font size
84 QFontMetrics fm(lcd_font);
85 font_width = fm.width(QChar(' '));
86 font_height = fm.height();
89 setFrameStyle(QFrame::Panel | QFrame::Sunken);
91 frame_width = frameWidth();
101 QSizePolicy EmulLCD::sizePolicy() const
103 return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
107 QSize EmulLCD::sizeHint() const
110 font_width * COLS + frame_width * 2,
111 font_height * ROWS + frame_width * 2);
115 void EmulLCD::drawContents(QPainter *p)
121 void EmulLCD::SetPainter(QPainter & p)
123 p.setBackgroundMode(OpaqueMode);
125 p.setBackgroundColor(bg_color);
129 void EmulLCD::RedrawText(QPainter & p)
135 for (r = 0; r < ROWS; r++)
136 for (c = 0; c < COLS; c++)
141 void EmulLCD::PrintChar(QPainter & p, int row, int col)
143 // Fetch char from DD RAM
144 unsigned char c = ddram[row][col];
146 // Map some Hitachi characters to ISO Latin1
150 c = 0xBA; // "degrees" glyph
154 c = 0xB5; // "micro" glyph
157 default: // all others
161 // Draw char on display
162 int x = col * font_width + frame_width;
163 int y = row * font_height + frame_width;
164 bool restore_colors = false;
166 if (show_cursor && (row == cr_row) && (col == cr_col))
168 // Exchange FG/BG colors
170 p.setBackgroundColor(fg_color);
171 restore_colors = true;
174 p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/,
175 QString(QChar(c)), 1);
179 // Restore FG/BG colors
181 p.setBackgroundColor(bg_color);
186 void EmulLCD::MoveCursor(int r, int c)
188 // Save old cursor position
189 int old_row = cr_row;
190 int old_col = cr_col;
197 if (show_cursor && (old_col != cr_col || old_row != cr_row))
203 PrintChar(p, cr_row, cr_col);
206 PrintChar(p, old_row, old_col);
211 void EmulLCD::ShowCursor(bool show)
215 // Draw (or erase) cursor
218 PrintChar(p, cr_row, cr_col);
222 void EmulLCD::AdvanceCursor()
225 if (cr_col == COLS - 1)
227 if (cr_row == ROWS - 1)
230 MoveCursor(cr_row + 1, 0);
233 MoveCursor(cr_row, cr_col + 1);
237 void EmulLCD::PutChar(unsigned char c)
241 // Write data in CGRAM
242 cgram[cgramaddr] = c;
244 // Auto increment CGRAM address
245 cgramaddr = (cgramaddr + 1) & 0x3F;
250 ddram[cr_row][cr_col] = c;
256 PrintChar(p, cr_row, cr_col);
263 char EmulLCD::GetChar()
265 char c = ddram[cr_row][cr_col];
271 void EmulLCD::Clear()
273 memset(ddram, ' ', sizeof(ddram));
281 void EmulLCD::SetCGRamAddr(unsigned char addr)
283 cgramaddr = addr & (sizeof(cgram) - 1);
287 // Hitachi LM044L register-level emulation
289 #define INI_DISPLAY 0x30
290 #define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */
291 #define ON_DISPLAY 0x0F /* Switch on display */
292 #define OFF_DISPLAY 0x08 /* Switch off display */
293 #define CLR_DISPLAY 0x01 /* Clear display */
294 #define CURSOR_BLOCK 0x0D /* Show cursor (block) */
295 #define CURSOR_LINE 0x0F /* Show cursor (line) */
296 #define CURSOR_OFF 0x0C /* Hide cursor */
297 #define MODE_DISPL 0x06
298 #define SHIFT_DISPLAY 0x18
299 #define MOVESHIFT_LEFT 0x00
300 #define MOVESHIFT_RIGHT 0x04
301 #define LCD_CGRAMADDR (1<<6)
302 #define LCD_DDRAMADDR (1<<7)
305 extern "C" void Emul_LCDWriteReg(unsigned char d)
307 static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 };
312 emul->emulLCD->Clear();
317 emul->emulLCD->ShowCursor(true);
321 emul->emulLCD->ShowCursor(false);
325 // Set DDRAM address?
326 if (d & LCD_DDRAMADDR)
328 for (int i = 0; i < EmulLCD::ROWS; i++)
330 if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS))
332 emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]);
337 else if (d & LCD_CGRAMADDR)
338 emul->emulLCD->SetCGRamAddr(d);
344 extern "C" unsigned char Emul_LCDReadReg(void)
346 return 0; /* This LCD model is never busy ;-) */
350 extern "C" void Emul_LCDWriteData(unsigned char d)
352 emul->emulLCD->PutChar(d);
356 extern "C" unsigned char Emul_LCDReadData(void)
358 return emul->emulLCD->GetChar();
361 #include "EmulLCD.moc"